Thank you for posting in Auth0 Community!
Tokens are intended for your application / application server, so if your application has a backend then the tokens should be stored there, and cookies used for session establishment, like shown in the Node.js quickstart for example.
If you do not have a backend, then the token should be stored in memory, and if the token is lost, use silent authentication to retrieve a new token. Our SDKs like the auth0-spa-js SDK (https://auth0.com/docs/libraries/auth0-spa-js) handle this for you.
Similarly you can use auth0.js SDK for regular web apps (https://auth0.com/docs/libraries/auth0js/v9).
When a new access token is needed, the application can make a
POST request back to the token endpoint using a grant type of
refresh_token (web applications need to include a client secret). To use a refresh token to obtain a new ID token, the authorization server would need to support OpenID Connect and the scope of the original request would need to include
While refresh tokens are often long-lived, the authorization server can invalidate them. Some of the reasons a refresh token may no longer be valid include:
- the authorization server has revoked the refresh token
- the user has revoked their consent for authorization
- the refresh token has expired
- the authentication policy for the resource has changed (e.g., originally the resource only used usernames and passwords, but now it requires MFA)
Because refresh tokens have the potential for a long lifetime, developers should ensure that strict storage requirements are in place to keep them from being leaked. For example, on web applications, refresh tokens should only leave the backend when being sent to the authorization server, and the backend should be secure. The client secret should be protected in a similar fashion. Mobile applications do not require a client secret, but they should still be sure to store refresh tokens somewhere only the client application can access.
Please let me know if you have any questions.