Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to secure client app (react) and API communication

Tags:

I have a client side React application and a Rails API from which the React app is fetching data.

As you would expect I only want my React application to be able to fetch data from the API and the rest of the world shouldn't be able to receive data from it.

Despite much searching I am yet to find the best way to secure the communication between the two applications.

I have read about JWT tokens and cookie based session authentication but the majority of articles seem to be focused on authentication of users (ie sign in/sign out) rather than communication between just the two applications.

The two apps will share the same domain so is it enough to rely on Cross Origin to secure communication?

Any advice really would be much appreciated.

like image 791
Tom Pinchen Avatar asked Mar 17 '18 11:03

Tom Pinchen


People also ask

How do you secure API calls from React?

If your API returns confidential data that should only be accessed by the appropriate user you will have to implement authentication of any sort. A user would then for example provide a password in order to call the API or he logged in before and got a token (e.g. JWT) that he sends with every request to authenticate.


2 Answers

If I got your question right you want your client(React App) to be the only client who can access your server.

As a solution to that you will have to have a combination of CORS and a JWT authorization, Thus I would suggest having a strict CORS to enable only your react app's domain to make a call to the server. To achieve this, I generally use a CORS npm module and configure the origin on my server or you can do it yourself as well.

var express = require('express') var cors = require('cors') var app = express()  var corsOptions = {   origin: 'http://example.com',   optionsSuccessStatus: 200 // some legacy browsers (IE11, various SmartTVs) choke on 204  } 

The above code allows only requests from example.com to be accepted by the server or have a look at this code for more dynamic whitelist & blacklist approach.

Now coming back to JWT, It is just a json encryption and decryption token which can share across API request to Authenticate as well as authorize the user.

For instance, you can store information like email, role, and nickname of the user in JWT and sent this encrypted JWT in each API request, the server authorizes this request and if true forwards to the requested API. This process of authorization and forwarding is generally implemented using an 'Interceptor' pattern wherein a middleware(Passport oAuth) does the check and auth before each API call.


Doing the above 2 things will ensure that only a client which has valid JWT token and domain address which you allowed to talk with the server. And this client will be your react app, as it is the only one with proper JWT and origin address.

So now your react app should just make sure that appropriate JWT token is passed in the API calls (post/get/put), most probably in the header of the API request, you can have an API helper service which does this for you and import that in component where-ever you make an API call. And your node server will implement the passport middleware pattern to authorize this JWT and filter non-authorized requests.

If you react app doesn't have a login, The JWT can be a client ID as well which recognizes your client as being legit. And just like user login, you can have you react app make a call to the server with data like a secret client id. This will return a JWT token. OR you can pre-generate a JWT token and you react app store it when it loads the first time, and by setting TTL and another config you can check if the Client which is making a call to your server is Old or New or some other fake client.

HTH

like image 166
damitj07 Avatar answered Sep 19 '22 17:09

damitj07


The case of cross origin domains is when you might need to implement CORS and a security like a blacklist. JWT is a little different, as you say authenticating users who need access to your api.

I believe as long as you don't enable CORS on your server, you'll be fine.

Note that this will not stop people from doing things like:

https://example.com/api/blah to access a part of your api if it is public. This is essentially the same as your front end doing the same because the client is served to the user, and the user then has full control over the client. They could change all instances of api calls in your app to a different endpoint and you couldn't stop them, just as they could just type it in the url bar. Any public endpoints on your api have to not share sensitive info.

like image 39
johnpyp Avatar answered Sep 19 '22 17:09

johnpyp