Securely storing auth token in React Frontend - reactjs

I am currently working on a single page react app. This app will not require any login and it will be publicly available.
I am making a POST request to a webhook of another API that I do not have access to and that I do not maintain. This API required me to send an authentication token via the POST. I wonder how I can securely store this token so that it does not get out in the world. I need to send it as is so storing it in a cookie that a backend provides is not an option. Storing in in JWT will not work as I can decode that without the secret.
Is there even a way to store the token without exposing it to the world?
I hope the issue is clear, if not let me know and I'll explain better.
Thank you all for your time!

I would usually have a local Express server running and proxy the request through that.
You would set up a route in your Express app that you would POST to from your React front-end, this Express route handler then makes the call to the external API from the server side which has the token to put in the header. Then the response is returned to your React front-end without it knowing anything about the external API or tokens.

You can't store the token in front-end. either you need to use
cookies/session to store the token. If you want to store the token you
need to encrypt it and store it will be the better option.
Please check here to understand the JWT token mechanism
if the web app doesn't have a login. you can't generate token without user details.
The token should be passed in the header of the request for best practices.

If you're using create-react-app to instantiate your React project, have you looked into using an environment variable to store the token? It's not 100% safe and secure, check here for the cons, but can be a quick fix without a separate proxy request. You can make an .env file (make sure to add it to your .gitignore if using git) in the root of your directory and define variables there. They need to start with REACT_APP, like REACT_APP_SECRET=1234 and can then be referenced where you need them in your app with process.env.REACT_APP_SECRET.
Read more about environments in React here.

Related

How to correctly store secret keys on React App?

I was happy lasts days using **.env **file with the npm dotenv package and saving there some secret keys i use on my React App...
On my first test opload I noticed that my webbApp runs ok EVEN without specifying the .env secret keys on the sever...
So then, was obious to feels like the secret keys are anywhere on the public files (and yes)
I was looking what im doing wrong, and found many documentation (official) that says literally:
WARNING: Do not store any secrets (such as private API keys) in your React app!
Environment variables are embedded into the build, anyone can view them by inspecting your app's files.
official doc here if anyone is looking for more info
After 3 or 4 heartAttacks I write this to ask for help on this concept problem.
Anyone knows some documentation where i can read and understant HOW to correctly save sercret keys on this kind of apps (react apps) ?
why the hell is not like all time backend .env files ?
Some info I found, says something about to serve the secret key ontime from another server.
And... sounds stupid for me, i mean: Ok, i can do that but.. its just stupid cause then:
or server will serve the sercret keys "free" vía GET or something like this without no-login-needed.
or webbApp would need a secret_login_key to login and get the secret key <- in this case, where to store that secret_login_key ? its a infinite bucle ? XD
So:
it is posible.. (of course it is) so TRULY store secret keys on React App ? but where and how ?xD
what's the way you store the secret keys on ur react App and u are proud of it?
of course the login typing from keyboard user/pass its the "easyway" to have or not have access tho private information but.. what if i need this to be automatic from my webApp ?
Thanks.
For automatic access to your webapp from the frontend (React), you need a bearer token that is stored in localstorage (bad idea) or as a cookie of the user's browser. Popular example of bearer token is JWT token.
This is how you generate a bearer token on the user's browser: by using Universal Login (login with Google/Fb/Github/Twitter etc) to a provider like Auth0.
React has to communicate with Auth0, Auth0 will authorise the user and return a bearer token that is stored in localstorage (bad idea)/cookie of the browser.
This is what you are trying to do:Call a protected API from React
This is the walk through example of how to do it: Basic Authentication Quick React Setup
Here are some example use cases with different application architecture scenarios:Application Architecture Scenarios
React's documentation is correct, secrets should not be used directly in the React project. But the problem is how to ensure only authorised users get access to protected paths. One way is to use username and password login but you said its the "easyway" and you need it to be automatic. So another way is to ensure authorisation by bearer token stored in localstorage(bad idea)/cookie of the user's browser - this creates a new problem: how to generate a bearer token to allow access. The solution is to use universal login by Auth0 (or Oauth, or OpenID, or Google Authenticator, or some other token generator that the user can possess (like a mobile app (Google Authenticator) or a hardware token)).
Sensitive data should not be on the frontend, you can use env for information like API_URL but not for tokens and passwords
Here is the possible ways to get sensitive data in the frontend
Http call to the backend where secrets are hashed
Http call to an external secret management tool like HashiCorp Vault
Use of httpOnly cookie that they couldn't be read from the frontend
If you are scripting user and password, you should try a tool like jscrambler to secure your build js files
When API calls are made from the frontend (i.e. your react app) anyone using your app can see the request that was made (with tokens, keys, etc.). You should always secret vars to an .env file and keep this file only on your local machine.The best way to handle this, in my opinion, is to use a framework like next or remix that allow you to create functions/api routes that run on the server. This way your frontend makes a request (no sensitive info there) to your server that has access to your keys/tokens. The real call to an external API will be made from the server (so users won't have access to any sensitive data). Not sure if this is something you're interested in but I feel like it's the best way to deal with API calls.
I suggest creating a ".env" to store all your secret keys.
In your ".env" file you can make this one
Eg:
REACT_APP_API_KEY=5155645fdsffsdfs
And in your component, you'll call it
Eg :
const apiKey = process.env.REACT_APP_API_KEY

Next.js and Nest.js authentification

I have a project where I use Next.js on the front-end and Nest.js on the back-end.
I want to use a JWT authentification method via email and password.
My question is:
What is the best way to implement an authentification for Next.js with custom Back-end.
I'm sending API requests through redux-saga to get some data from back-end.
For me the Set-Cookies from the back-end not work. It's not applying on the client browser.
For now my possible solution is to create a custom axios instance and somehow do the Auth check there.
But I'm sure there should be a better solution, thanks for help!
For now my possible solution is to create a custom axios instance and somehow do the Auth check there.
Yes. This is the correct way of going about it. Give the token to whatever you use for queries and let it handle it for you.
You have a number of different ways of achieving this.
Provide it via a side-effect
Whenever a login event happens, run a side-effect to configure your axios instance to always send the newly acquired token with each request
Set the token in your cookies or localstorage and let axios retrieve it for each request
Set the token in a context and only make requests through that context with a hook

What is the best way to store an admin API token in Next.js ? Feel like storing it client side as http only cookie is risky

I'm working on a e-commerce using next.js and sylius API and the API admin routes are secured using JWT. So in order to fetch products (for example), i need to login to the API, get the token and then fetch the products using the token. The most common method to be able to send the token on every new requests to the API is to store it in a HTTP-only cookie.
As the pages are generated statically, i feel i don't need (and want) to expose the API token to the client. So i'm wondering the best way to store the token ?
Here the different options i have in mind right now:
store the token as a http only cookie and use it server side (with a proxy using next js API pages) in order to call the sylius API. Like i said, i'm not confortable to store the API token into the client, it seems risky to me, as it will be exposed to everyone, and with that token you can access the admin API.
configure the API in order to prevent the token from expiring, and store it in the next js app as an environnement variable (.env.local), so that it's not exposed to the client and can be used for fetching the api when generating static pages. The official ecommerce theme of Next.Js seems to use that method (https://github.com/vercel/commerce/blob/f770ad7a91059a2ecfbb9de1bac111dfe7016124/framework/bigcommerce/api/index.ts#L82)
store the token somewhere in the next js structure but not as an environnement variable (maybe a config file?), so that it can be replaced if necessary (if the token expires etc).
get the token and store it in the react state as is it will be used once only for generating all static pages. On each build the token will be asked again by the API and then used for fetching the API for exporting the static pages with the content. It don't need to be saved more time than the building step.
For me the last option seems better but i feel i'm missing something there, i'm kinda new to next, so i'm not sure exactly if its a good solution.
Thanks :)
I get a great answer from a reddit user ("supermaguireray"), so i post it as an answer here:
"First of all, in any session management mechanism the correct information needs to live on the correct domains, what I mean is that your client can only have access to a identification information, but never to data used in the server, these can be applied to a server-side session, when a ID for the user data stored on the server is sent to the client (preferably encrypted), or in a JWT where a encrypted string is sent to the client (identification), and decrypted on the server (Data).
With that said, the only reason you should send the API token to the client is if you need to fetch data directly from a browser. Storing as a httpOnly cookie is the most secure way.
In case you only need the cookie fetch data to the next backend, to render your SSG or ISR pages, there is no need to send a cookie to the client. Just store the token in your server. I would store it as env variable. Use next.config.js->runtime-configuration.
Or, you can keep a expiration date for the token, and store the credentials, maybe even in a DynamoDB or FaunaDB app."

How to send POST login request to a rails api-only app using React?

I have a working rails RESTful api-only app.
I use Postman to consume that api. Now, to use the api the user have to login to http://localhost:3002/authenticate first by setting content-type to application-json in Header then Email and Password's value in body. After sending the POST request to the server I get auth-token as a json response. Then after successful login I have to pass that auth-token as a Authorization key in each GET request to get respective data.
Now, I want to build a UI for that back-end api as I learn React js. But till now all tutorials I could find was how to send GET requests without any authorization factor. And they are using axios, redux etc.
Can any-one please guide me on where should I start or how to
approach this problem?
Do I necessarily have to use a third-party library for this purpose?
If so which will be better axios or redux??
Any beginner friendly tutorial link would be of tremendous help
How start
Securing React Redux Apps With JWT Tokens - Rajaraodv explains how you get a jwt token and how to keep it in the front end app. I think this way will fits for you.
Keep the auth-token
Rajaraodv uses localStorage to keep the jwt token, you can use the same or keep directly in redux store, it's your choice, the best manner that fits you.
Ajax call
You can use Axios to make Ajax calls, or use fetchApi from the browser as Rajaraodv did, it's up to you.
Explains
"If so which will be better axios or redux??" these two libraries are totally different, each with it's own purpose.

Session Token Authentication Security

I need some advice regarding using session tokens to authenticate users. I am building an AngularJS app which uses an API to tie in with the backend. I am only building the front end, not the backend. The documentation states that all calls to the API have a session token attached in the body of the request (POST).
I would like to know about the security of storing this token in localStorage. That is where I am storing it now and retrieving and attaching it to each API request. After login, the server sends the session token in the body and I save it from there.
There is no documentation about an x-access-token header that should be sent with the request made to the server. It is not being checked server side. What are the implications of this? I feel that it is susceptible to attacks without this added layer of security.
My main concern is the security of this setup. I want to know what the best setup is to make sure this app is as secure as possible and recommend changes to the way the backend is setup to facilitate this.
Thanks!
As you tell, you are only working on the UI part and not the backend. It is up to the backend team to ensure headers are properly evaluated and security is enforced (btw request headers do not belong to request body). Just put the token into the x-access-token header as they tell.
Storing the token inside the localStorage gives you a little more control over the cookie: You will not accidentally send it to unnecessary URLs. However, older browsers do not support it - you may need to use a shim for that.
In a case of SPA, you may consider not storing the token at all: It could be fetched each time your application is accessed and then stored within a service in angularjs, but it depends how your fetch/login operation is implemented (is it always interactive, how long does it take, etc).
I would suggest use $cookies rather than localstorage. As localstorage does not support some legacy browser.
I am using cookies to store token in my project

Resources