Token Storage
Overview
Key Concepts
-
How you decide to store your token is crucial to defending your application against malicious attacks.
-
Review scenarios for each application type.
Decide which method best supports your technology.
Securing SPAs that make API calls come with their own set of concerns. You'll need to ensure that tokens and other sensitive data are not vulnerable to cross-site scripting (XSS) and can't be read by malicious JavaScript.
To learn more, see JWT Handbook and The Ultimate Guide to Next.js Authentication with Auth0.
Next.js static site scenarios
When you're building a Next.js application, authentication might be needed in the following cases:
When accessing a page
When accessing an API route
When your application calls an API hosted outside of your Next.js application on behalf of the user
Where a server is available, your app can handle the interaction with Auth0 and create a session, but in this model, we don't have a backend. All of the work happens on the frontend:
The user is redirected to Auth0.
When the user is successfully signed in, they will be redirected back to the application.
The client-side will complete the code exchange with Auth0 and retrieve the user's
id_token
andaccess_token
which will be stored in memory.
If your app is using a sign in scenario that doesn't require API calls, only an ID token is required. There is no need to store it. You can validate it and get the data from it that you required.
If your app needs to call APIs on behalf of the user, access tokens and (optionally) refresh tokens are needed. These can be stored server-side or in a session cookie. The cookie needs to be encrypted and have a maximum size of 4 KB. If the data to be stored is large, storing tokens in the session cookie is not a viable option.
Use the following flow types in these scenarios:
Store tokens in a secure storage that the OS offers and limit access to that storage. For example, leverage KeyStore for Android and KeyChain for iOS.
Use the following flow types in these scenarios:
We recommend using the Auth0 SPA SDK to handle token storage, session management, and other details for you.
When the SPA calls only an API that is served from a domain that can share cookies with the domain of the SPA, no tokens are needed. OAuth adds additional attack vectors without providing any additional value and should be avoided in favor of a traditional cookie-based approach.
When the SPA calls multiple APIs that reside in a different domain, access, and optionally, refresh tokens are needed.
If the SPA backend can handle the API calls, then it functions similar to a tradition web application that handle tokens server-side using:
If the SPA backend cannot handle the API calls, then it functions similar to a mobile application that stores tokens in the SPA backend, but the SPA needs to fetch the tokens from the backend to perform requests to the API. A protocol needs to be established between the backend and the SPA to allow the secure transfer of the token from the backend to the SPA.
If you have a SPA with no corresponding backend server, your SPA should request new tokens on login and store them in memory without any persistence. To make API calls, your SPA would then use the in-memory copy of the token.
For more details, see Auth0 SPA SDK in GitHub.
Browser in-memory scenarios
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.
Use Auth0 SPA SDK whose default storage option is in-memory storage to leverage both Web Workers and JavaScript closures depending on the type of token.
Browser local storage scenarios
Using browser local storage can be a viable alternative to mechanisms that require retrieving the access token from an iframe and to cookie-based authentication across domains when these are not possible due to browser restrictions (for example, ITP2).
To reduce security risks if your SPA is using implicit (we recommend using authorization code flow with PKCE instead) or hybrid flows, you can reduce the absolute token expiration time. This reduces the impact of a reflected XSS attack (but not of a persistent one). To reduce the expiration time, go to Dashboard > APIs > Settings > Token Expiration For Browser Flows (Seconds).
Reduce the amount of third-party JavaScript code included from a source outside your domain to the minimum needed (such as links to jQuery, Bootstrap, Google Analytics etc.) Reducing third-party JS code reduces the possibility of an XSS vulnerability. Performing Subresource Integrity (SRI) checking in third-party scripts (where possible) to verify that the resources fetched are delivered without unexpected manipulation is also more secure.