6

I have a ReactJs frontend app that connects to a few API services. A few of these API services require me to pass my appId and appSecret during initial login.

I currently have them in a js file which gets minified and bundled but I feel I'm still exposing my app credentials to savvy intruders.

What's the right way to protect them?

Sam
  • 26,817
  • 58
  • 206
  • 383
  • [This article](http://billpatrianakos.me/blog/2016/02/15/securing-api-keys-in-a-javascript-single-page-app/) seems to have what you want. – E_net4 Oct 19 '17 at 20:02
  • 2
    Don't ever put secret API credentials in front end files. Usually you'd want your backend to handle the pass off of data to an external authenticated API. – Devon Bessemer Oct 19 '17 at 20:05
  • Some guy just gave a great answer here: https://stackoverflow.com/questions/46838015/using-api-keys-in-a-react-app – Chase DeAnda Oct 19 '17 at 21:22
  • I'm not really clear how this would work. There are cases where the API call to the third party must be made from the front-end client e.g. ReactJs or a mobile app. For example, take a file upload service client I use. I have no control over their client code but I need to invoke it from my React app using their access keys. Even if I keep these keys on the server and make an API call to get them, I'm still exposing the end-point that will return the API keys. I could use an obfuscated URL but nevertheless, that URL will be in my client code. – Sam Oct 20 '17 at 14:16
  • There's also the case where I allow third parties to access my API. I will issue them access keys and require them to send them along in their API calls. If they first make an API call to get these keys, the endpoint that returns them will be hard-coded into their app. I will need such keys to authenticate them so the only way to return their access keys from an API call has to be from an endpoint that does not require their app to be authenticated first. In other words, I didn't solve the problem. At best, I just made it slightly more inconvenient to hackers. – Sam Oct 20 '17 at 14:20

1 Answers1

3

I Read the comments and saw that you were still confused, but a more detailed explanation was taking more space than allowed in a comment so posting a more detailed explanation as an answer.

The idea is that you use your server as a proxy for all requests and responses.

  • Case 1: You need to make a request to an API from the front-end - The front-end will issue a request to your server without the API credentials (because they aren't stored on the front-end app). Your server will authenticate the request if necessary (as in it checks if your user is logged into your server), make sure that the logged in user has permissions to use the api services (only if you have multiple user roles), and then your server will make the api request using the credentials stored on the server. The server then responds to the front-end client, which is waiting for a response to its request, with either the direct results of the API request or a version of them that you did some pre-processing / formatting to on the server. In this way, your API credentials can be stored secretly on your server, and only the people you want to give access to use your api credentials (via your front-end client app experience) are allowed to use it.
  • Case 2: you make your API public to authenticated users - A common way to do this is to issue some sort of key to the people you want to provide access to. If they lose it they are either out of luck, or you must provide them some way to contact you / your company / someone who manages this for you, and allow them to prove to you somehow that they are who they say they are and that they should have access to your api. It's pretty similar to the situation where if you forget your password on a website, you have to prove that you are you before you can reset your password, usually by clicking a link that they will email to the email account associated with the account that you are saying lost the password. Anyhow, assuming they have their passkey, it should be sent with every request to your api and you need to make sure it is a correct key for every request that you process.

These aren't the only ways to handle these kinds of interactions, but they are some of the more common ways. Case 1 and 2 are different because in case 1, there is a client (front-end) that needs to get data from an API. The API's credentials are secured by being stored and used only by your server. In this situation you can optionally restrict access from everyone that uses your app, to everyone that is authenticated on your app (you must implement a login system), to only people that are logged in and have a certain permission level (you will have to implement roles). In case 2, there is no client app, and someone is directly accessing your API. You still need to authenticate them, so you just issue them a secret key one time, and they pass that key every time they make a request.

Dude
  • 931
  • 6
  • 16