I am using the Auth0 SPA JavaScript SDK with refresh tokens configured including refresh token expiration and rotation for security measures.
My flow is functional and utilizes the loginWithRedirect and getTokenSilently methods exposed by the SDK but one thing I have not been able to figure out is if (I or the SDK) are responsible for using the refresh tokens to obtain new access tokens?
From reading related community posts and information online, it sounds like that responsibility used to be on the developer in older versions, however verbiage throughout documentation for the current SDK seems to imply that the SDK should automatically issue a request to get new access tokens before it expires?
In any case I have noticed that changing the TTL for my APIâs access token seems to control when users are forced to login again. Therefore it seems that my refresh tokens are not actually being utilized as their TTLâs are much longer than the access tokenâs.
For some additional context I am configuring the Auth0Client with a cacheLocation: 'localstorage' and authorizationParams.scope: âopenid profile email offline_accessâ and my package version is â@auth0/auth0-spa-js": â2.5.0â.
Overall I am just trying to understand if I am missing something here conceptually or in my own auth flow, thank you.
Hi @kbrown84,
Welcome to the Auth0m Community!
Youâre right about the information that you have researched online, as the latest SPA SDKs can use the refresh tokens automatically. But in oder for that to work properly within the integration of your app with the SDK, you will have to configure the Auth0 Client to include the useRefreshTokens: true as well, such as:
const auth0 = await createAuth0Client({
domain: '<AUTH0_DOMAIN>',
clientId: '<AUTH0_CLIENT_ID>',
useRefreshTokens: true,
authorizationParams: {
redirect_uri: '<MY_CALLBACK_URL>',
audience: 'https://your_audience',
scope: 'openid profile email offline_access'
}
});
This Knowledge Base Article - How to Use Refresh Tokens in a SPA will provide a step-by-step documentation of the process of enabling refresh tokens.
Additionally I would also recommend enabling the useRefreshTokensFallback: true since the SDK will still fall back to iframe-based silent authentication using the Auth0 session if the Refresh Token exchange fails, generating an extended session of the user even after the expiration of the Refresh Tokenâs absolute time.
Hope this helps!
Best regards,
Remus
1 Like
Thank you for the follow-up! I can confirm I was also previously using useRefreshTokens: true but I also included useRefreshTokensFallback: true and went through the article you linked and can confirm that each step is implemented and accounted for.
I am still running into the same issue it seems. For easier testing I set my APIâs Maximum access token lifetime to 120 secs and the implicit / hybrid flow lifetime to half of that (though Iâm not sure if that one is relevant in my case?).
What Iâm seeing is that if I refresh my home page after 2 minutes and while monitoring my network tab, there is a request ending with /oauth/token returning a 403 and immediately after I get returned to my login page.
That token request payload includes the following:
client_id: <my app's client-id>
grant_type: refresh_token
refresh_token: <a refresh token>
redirect_uri: <my redirect url>
Is this expected or is this illustrating the refresh token request failing to get a valid access token upon the access token expiring?
Hi @kbrown84
I will continue to assist you regarding this matter for the time being. I am sorry about the delayed reply to your newest update.
Could you ensure that you have enabled Refresh Token Rotation for your application?
As mentioned in the documentation available for SPA JS:
Note This configuration option requires Rotating Refresh Tokens to be enabled for your Auth0 Tenant.
You can check this support article related to the 403 error that you are receiving on this matter with possible troubleshooting steps.
Let me know if the information above is helpful or if you still experience issues with refresh tokens in your application!
Kind Regards,
Nik
Thank you for the reply, I can confirm that yes I have Refresh Token Rotation enabled with the following, settings:
Also when reproâing the /oauth/token 403 I get no HTTP response body on the error to go off of. When this occurs if I inspect my logs in my tenant I just see an error for MFA required and nothing specific to a refresh token failure.
So I have a few questions to further narrow down some paths:
- Is a Rotation Overlap Period of 0 potentially problematic? That was either default or was set up prior in my tenant by another engineer.
- Is MFA able to work with refresh tokens? I have requirements currently to support MFA with both email and then sequentially an OTP.
- From one of the solutions in the troubleshooting doc the verbiage sounds like itâs implying there is some manual logic needed to handle the refresh tokens, however I thought that this was automated when using the SDK? (See the highlighted bullet points here):
Hi again!
Sorry for the delayed response!
- Is a Rotation Overlap Period of 0 potentially problematic? That was either default or was set up prior in my tenant by another engineer.
That should not be an issue. You could try testing various settings to see if there are any changes.
- Is MFA able to work with refresh tokens? I have requirements currently to support MFA with both email and then sequentially an OTP.
Yes it does, however, you would need to handle the logic of bypassing MFA within a PostLogin Action whenever tokens are refreshed since the application would throw an âMFA Requiredâ error during token refresh or silent authentication.
- From one of the solutions in the troubleshooting doc the verbiage sounds like itâs implying there is some manual logic needed to handle the refresh tokens, however I thought that this was automated when using the SDK? (See the highlighted bullet points here)
The points that you are referring to would be indeed manual login that your application should handle. The refresh of the tokens is handled automatically however your application should ensure that the token are being stored properly (as in the storage location, either within a cookie or the local storage of the device which you already have done) and to make sure the tokens are being replace and an expired one is not being used after the refresh.
By any chance, have you tried to replicate this issue using our SPA JS sample application?
Kind Regards,
Nik
Thanks for the clarifications, that narrows it down and I am suspicious now that the MFA is the core issue because I can confirm that I do not have a PostLogin Action to bypass MFA setup yet.
I found this example in the docs for bypassing, is this all the action needs to do is implement a fail fast if the protocol is oauth2-refresh-token in order to bypass? (I will get back to you once again after testing this out).
From your other response to that 3rd question, it sounds like regardless there should be some additional manual logic around storing and replacing the tokens (which is not provided by SDK)?
I thought that was already handled by the SDK / Auth0 when you set:
useRefreshTokens: true, cacheLocation: 'localstorage' in the SDK client? If thatâs not the case can you link me to where an example of manually handling the refresh tokens takes place?
Yes, that is correct, if you apply the right conditions, you should be able to bypass the MFA for your users during token refresh.
I thought that was already handled by the SDK / Auth0 when you set:
useRefreshTokens: true, cacheLocation: 'localstorage' in the SDK client? If thatâs not the case can you link me to where an example of manually handling the refresh tokens takes place?
The SDK should take care of everything as long as everything is configured correctly. In regards to what I have mentioned, if the application does not handle the points mentioned above (for some reason or due to misconfiguration), the refresh tokens might not work. As I have said above, you seem to handle everything correctly, just make sure your application is not doing something it is not supposed to in regards to the refresh tokens.
If I can help with anything else, let me know!
Kind Regards,
Nik
Hey there Nik! Iâm happy to confirm that the missing MFA bypass action for refresh tokens was the solution to the issue I was having

I want to note one additional gotcha that I came across in case someone else is running into this same issue, hopefully it saves others time:
Initially I created a new custom action using the exact code snippet from docs link I put before (also here). That did not immediately work even if I put that as the first or last of my post-login triggers in the action chain.
After fully disabling MFA and seeing that refresh token requests started working, I went back to my actions and found that I also had another post-login action which had the following in an onExecutePostLogin callback:
api.multifactor.enable("any", { allowRememberBrowser: false });
This was from an earlier app requirement to remove the âRemember for 30 daysâ checkbox in the login flow which I still needed.
I pulled this into that new action I created instead after the fail fast MFA bypass check, then refresh tokens started working with MFA enabled, and while still disabling the remember browser setting 
Therefore it seems that having another action which enables some MFA setting will still cause the bypass to fail, no matter what order you chain the actions in the post-login triggers.
Thank you again for all of your help @nik.baleca and also to @remus.ivan initially 
1 Like
Thanks for letting us know!
Whenever you have questions or issues, you can always post a new topic! Hope to see you around!
Kind Regards,
Nik
1 Like