Securing React application with in-memory JWT token

I configured my React SPA to work with Keycloak using a “Public” SSO client.

I’m storing the JWT Access Token inside the Redux store (dev-tools disabled in production).

I’m not storing anything inside the Local Storage, Session Storage or as a Cookie.

Since my token is inside the Redux store, it’s fair to say that the token is stored in-memory (on page refresh you will be briefly redirected back to Keycloak).

Following this documentation page from Auth0: https://auth0.com/docs/secure/security-guidance/data-security/token-storage#browser-in-memory-scenariosbundles

Auth0 recommends storing tokens in browser memory as the most secure option. Using Web Workers to handle the transmission and storage of tokens is the best way to protect the tokens, as Web Workers run in a separate global scope than the rest of the application. Use Auth0 SPA SDK whose default storage option is in-memory storage leveraging Web Workers. If you cannot use Web Workers, Auth0 recommends as an alternative that you use JavaScript closures to emulate private methods.

So, in my case, I’m using “JavaScript closures to emulate private methods” approach (CRA).

The Redux store is not publicly accessible and the React process is contained within the JavaScript memory at runtime.

I’m also enforcing HTTPS, I added Node Helmet and I have a quite strong CSP policy both inside Keycloak and React application. Not to mention that my “Public” SSO client is very restrictive in terms of “Web Origins” and “Redirect URLs”.

I think my solution is pretty secure and solid, but other people thinks differently.

What do you think?

Hi @circle1extra,

Welcome to the Auth0 Community!

Thanks for creating a detailed topic.

Yes, we recommend storing tokens in memory for SPAs like you mentioned (alternatively we provide Refresh Token Rotation for persistent sessions, but this is a bit different).

Is there something specific you are concerned about with your setup? We don’t do individual security audits here for obvious reasons, but I’d be happy to run a question by the team if you have a specific concern. (e.g. Is it okay to store a token in Redux?)