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.
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:
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.
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?
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):
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.
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.
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.