6

I am building a static website, HTML, CSS, and Vanilla JS. I came to a point where I have to use MailChamp to send emails to the client whenever there is a form submission. Not so tricky, docs are very clear on how to do an API call. But I need to send an API_KEY with every request. Which is a problem. I do not want to save this secret key in the code. I have added it as a secret on github repo. But I am not sure how I can access it on Vanilla JS files. I tried the following,

process.env.API_KEY and API_KEY

I am getting this error, sendEmail.js:1 Uncaught ReferenceError: process is not defined

Which makes sense, because it's a static website. But I cannot think of any other way. If it was a node process it would have been very simple :/


Let's say I create an API endpoint, and the server where I can securely save API_KEY, how would I authenticate the request coming from the front-end/static website? Assuming that I cannot securely save the token on the client side.

Hafiz Temuri
  • 3,882
  • 6
  • 41
  • 66
  • 1
    Does this answer your question? [How to Hide an API Key in Client-Side Javascript](https://stackoverflow.com/questions/38237673/how-to-hide-an-api-key-in-client-side-javascript) – esqew Dec 21 '20 at 02:03
  • @esqew well yes and no, I already knew it will be impossible to secure the key in the client browser. I was hoping to know if there is any possibility to have MailChamp take care of it without needing a back-end server. – Hafiz Temuri Dec 21 '20 at 03:20
  • How would it be possible for your mail service to discern what subscription to bill if you didn’t have to provide authentication information for each call...? Aside, what is “MailChamp”? I’m not aware of any such service, so I can’t say for certain if they would support such a design. Mind linking their documentation or other supporting material? Or are you referring to “Mail*Chimp*”? – esqew Dec 21 '20 at 03:48
  • Sorry, I keep misspelling them. Yes, it is MailChimp – Hafiz Temuri Dec 21 '20 at 04:02
  • In any case, my question still stands: how could your mail service know whom to bill if not for passing of these sorts of credentials? – esqew Dec 21 '20 at 04:04
  • @esqew by adding their ` – Hafiz Temuri Dec 21 '20 at 04:06
  • The script you’re alluding to provides standard functionality to call their API. Every MailChimp user uses the same copy. It doesn’t/shouldn’t include your personal token-based authentication strings. Without these, the API receiving the calls wouldn’t be able to tell anyone apart. – esqew Dec 21 '20 at 04:08
  • The web API request does contain the origin?! So basically you register your web URL – Hafiz Temuri Dec 21 '20 at 04:09
  • If you’re talking about the `Referer` header, these can be spoofed extremely trivially by malicious or incompetent actors. What would be stopping me or anyone else from modifying my own calls to the same endpoint, sending along a modified `Referer` to avoid paying for the request myself and passing a mountainous bill along to you? – esqew Dec 21 '20 at 04:11
  • Maybe you are right, but I was hoping that it could be taken care of by SSL connection or something of that sort. – Hafiz Temuri Dec 21 '20 at 04:12
  • This is getting wildly off topic from the original premise of the question, so I will answer your last comment succinctly: SSL only provides encryption end-to-end. It does not prevent anyone from modifying or creating their own requests to exploit a design such as the one you propose. In short, you’ll need an intermediary server to proxy these requests so that you don’t leak your secret keys to your end users. – esqew Dec 21 '20 at 04:15
  • @esqew Deep down I already knew that. But I was hoping to avoid running a back-end API for such a small task. I hate to admit, but that is the only way :/ Appreciate your time! – Hafiz Temuri Dec 21 '20 at 04:19
  • @esqew I updated my question, I was wondering if I can have your input. – Hafiz Temuri Dec 21 '20 at 05:30

1 Answers1

3

There is no way to do it the way you want, i.e. with pure front end (FE) because it would mean that you need to send your secrets to them. Whatever you send to the front end will always be accessible to your users, so it's not safe. What you need to have is the back-end (BE), some kind of server that will receive an async call from the FE, connect to the external API and do whatever you want it to do, and then send some kind of confirmation to the FE that the process was successful. Now, the BE will know your secrets, and this is fine because you control it and the users won't have access to it directly.

Now, you do not always need a full-blown application for that, some people are getting stuff done with platforms like Firebase, that can handle authentication of users for example for you.

IvanD
  • 2,728
  • 14
  • 26
  • @hafiz-temuri, please accept my answer if it helped you :) – IvanD Dec 21 '20 at 03:20
  • Is it possible to receive emails on form submission without using a service or dynamic language like PHP? If the browser can do an API call, why not send an email?! Because of email spamming? Which do get every day. – Hafiz Temuri Dec 21 '20 at 03:25
  • @HafizTemuri Can you imagine if any arbitrary website you simply browsed to could instruct your browser to send emails on your behalf? If rudimentary malware could send emails *as you*? Browsers aren’t email clients, and for good reason. – esqew Dec 21 '20 at 03:47
  • @esqew Isn't it how email scamming works, they do pretend to be someone else. – Hafiz Temuri Dec 21 '20 at 04:01
  • @HafizTemuri Not at all, actually. There are many methods email spammers have used over time but sending email as another user via a call to any method as defined within the JavaScript standard has not been one. Because this functionality has never been part of the standard. – esqew Dec 21 '20 at 04:03
  • Ok, let's say I create an endpoint how would I create a token to secure the call from the front-end to the back-end? Assuming that I cannot save a token in the front-end, how would I authenticate the request coming from the front-end? – Hafiz Temuri Dec 21 '20 at 04:58
  • The request will happen from the back-end side. Your back-end will validate the data received from the FE, and do the API call itself. All this time only the BE has the API key. – IvanD Dec 21 '20 at 05:36
  • Yes, but then anyone can call that back-end endpoint. How would I authorize the call coming from the front-end without any user login? – Hafiz Temuri Dec 21 '20 at 16:30
  • You can't without user login. You need to differentiate people who are your users and strangers somehow. https://stackoverflow.com/questions/47841937/best-way-to-handle-api-calls-from-frontend – IvanD Dec 21 '20 at 17:28
  • Hey @hafiz-temuri, please accept my question if it was helpful :) – IvanD Dec 25 '20 at 01:05