I have been searching for a satisfying answer for an hour and I still can't figure out the answer to the question: how to securely store the JWT token on the client side with React?
From what I have read, the localStorage solution in undesirable as it's accessible from third-party scripts. A more secure solution proposed is to use a HttpOnly cookie, but the problem is, it is inaccessible via js, hence it is useless in React.
Therefore, how can I securely store a JWT token on the client side?
To keep them secure, you should always store JWTs inside an httpOnly cookie. This is a special kind of cookie that's only sent in HTTP requests to the server. It's never accessible (both for reading or writing) from JavaScript running in the browser.
A key component is a JWT token that holds authentication data that can be confidentially transmitted between clients. In SPA, developers commonly store the JWT token in the browser's local storage and include it in an authorization header for each request, possibly leading to security threats.
Adding JWT Token in React. To add JWT token in the header, we have a function defined in the auth service. Apart from login function, we have some util method defined here to get the header with JWT in it, get logged in user details, etc. AuthService.js
On success ( user credentials are good) setProfile helper is called to save the user information in the app store. The above code snippet extracts and saves the JWT Token for later use (logout, user profile request).
For example, we have added actual role of the user in above JWT token and the sub contains the actual uername of the user. Signature provides the security to the JWT token and ensures that the token is not changed on the way.
And for the subsequent request made from the react app, the JWT is taken from local storage and set in the API request Authorization header to maintain the user session Values in local storage are accessible by javascript, so any cross-site script can get the JWT from local storage and gain your account access.
In short - you can't securely store token in the browser. If your code has access to the token, then any attacker can also get access to it. That said you can mitigate some risks and decide on a solution which might be "secure enough" for your needs.
E.g. it might be enough for you to keep tokens in the local storage, if losing such a token does not pose a great risk - maybe the data handled by your website is not sensitive.
A viable option is to keep the token in the memory. This way it's a bit more complicated to steal it. Then of course you need to get a new token every time you refresh the page, but you might use SSO cookies to automatically get new tokens in the background.
If you want to go with current security best practices for SPAs, you should investigate the Backend-For-Frontend pattern. You add a lightweight backend component which handles tokens and OAuth flows, and which uses regular cookie-based sessions in communication with your React app. At Curity we created an example implementation of such a component, which you could use as inspiration: https://github.com/curityio/bff-node-express
You can have a look at this great video: https://www.youtube.com/watch?v=lEnbi4KClVw where Philippe de Ryck goes into detail of why it's not possible to securely store tokens in SPAs.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With