62

I have a React app that uses two third-party services. The app was started using react-create-app.

Both of these services require a API key.

One key is supplied via a script tag, like this:

<script type="text/javascript" src="https://myapi?key=MY_KEY">
</script>

The other API key is used in a request. I store the actual key in a constant and use it to form the request. Like this:

const MY_OTHER_KEY = 'MY_OTHER_KEY'
let url = `http://myotherapi?key=${MY_OTHER_KEY}&q=${query}`

Google's best practice tips on handling API keys says:

Do not embed API keys directly in code

This brings me to my first question:

1. How to use variables in index.html?

In my index.html file, I have two tags that look like this:

<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">

Obviously, %PUBLIC_URL%is a variable. How can I add a variable %MY_KEY% as to avoid embedding the API key directly in my code?

To get something like this:

<script type="text/javascript" src="https://myapi?key=%MY_KEY%">
</script>

Related to this question, is it safe to have the API key stored in a constant, like I do for MY_OTHER_KEY?

Google also says:

Do not store API keys in files inside your application's source tree

This brings me to my second question:

2. Doesn't the API key still end up in the bundle?

Say I do what Google says and I

... store them in environment variables or in files outside of your application's source tree

Say I store a key in a outside file. That file will, I assume, be read at some point and it's contents either copied in the bundle or referenced in some other way. In the end, won't the key still be visible in the bundle, except maybe harder to find? How does this help exactly?

3. Is there a canonic way of using API keys in a react app? Or is it up to the individual developer?

Self explanatory, I'm looking for the react way of solving this issue, if there is one.

Thank you for your help!

VLAZ
  • 26,331
  • 9
  • 49
  • 67
mayk93
  • 1,489
  • 3
  • 17
  • 31

1 Answers1

67

1. How to use variables in index.html?

Answer 1 : Please go through Adding Custom Environment Variables to find out how to add environment variables of the type that you have shown as an example.

2. Doesn't the API key still end up in the bundle?

Answer 2 : Even when you have your key (MY_KEY) as an environment variable in the script tag, it will get rendered on the page and will be visible. Generally, these are browser keys and are intended to be used on the client side. These can be restricted by providing Http Referer header in your request. More on the efficacy of securing these keys here. However API keys (like MY_OTHER_KEY) are not supposed to be used on the client side and should not be rendered in the script tag or stored in the client side JS.

3. Is there a canonic way of using API keys in a react app? Or is it up to the individual developer?

Answer 3: The canonical way to use a third party API key is for your client side app to send a request to your backend API. Your backend API then formats the request as per the third-party API, adds the key and makes the call to the third-party API. Once it receives the response, it can either unpack it and translate it into domain objects which your front-end app would understand or send the raw response back to the front-end app. In this way, the API key stays at the backend and is never sent to the client-side.

marcelosalloum
  • 3,481
  • 4
  • 39
  • 63
palsrealm
  • 5,083
  • 1
  • 20
  • 25
  • 1
    as for QA 3 - I wonder what about keys used for oAuth services where the common practice is for them to be used by the client. I can imagine an approach where its the server using api token and then returning one time url for the client to talk to the oAuth but this would be rather something extra and most probably is not supported in most existing cases... – ciekawy Jul 24 '19 at 16:05
  • 15
    Answer 3 strikes me as negating the advantage to react. What if your endpoints are all external api's? Now we need a back end simply to protect credentials, and, we're introducing two api calls for every request, basically? Seems there has to be a better way – wkhatch Dec 03 '19 at 22:14
  • 3
    A link that you provided in answer 1 says: "WARNING: Do not store any secrets (such as private API keys) in your React app!". – karlosos Jun 11 '20 at 11:09
  • @karlosos that advice is correct. you only store public keys which would be available to everyone. If you want to use private keys then read answer 3. – palsrealm Oct 19 '22 at 10:13
  • @wkhatch the points you make are valid. An easy alternative to the number of calls is to fetch the key from your backend at runtime and store it locally in state which you can then use for all subsequent api calls. You would still need a backend or any other form of secure external storage from which you can fetch the api key, since the requirement here is not to bundle the key with the app. – palsrealm Oct 19 '22 at 10:22
  • @palsrealm What would prevent the React app user from using dev tools and breaking into the code and console.logging the state just before the api call is made ? – Ray Gllisse Aug 19 '23 at 17:59