I am building an Angular service (AuthService) like you have in your Quick Start guide. I need to be able to exchange our Auth0 accessToken for a Firebase token whenever the accessToken is updated. To do this I’ve added a refresh timer in my AuthService to manually invoke getTokenSilently() to get the latest accessToken and then call a REST service to mint a new Firebase token.
The problem I’m having is if I set that refresh timer to run prior to the accessToken expiration, I just receive back the same accessToken (that is about to expire). If I set it to run at the same time or slightly after the accessToken expiration, I get an error ID token is required but missing. I have enabled refresh token rotation on the Auth0 application and enabled offline_access on the Auth0 API for the accessToken. The refresh_token grant type is also applied to the Auth0 application. I see the refresh_token stored in localStorage along with the id_token, access_token, etc. so I know I’m getting it. It seems like everything is configured correctly to enable refresh token use.
Perhaps I don’t really understand how the refresh_token is used within the bowels of auth0-spa-js. My assumption was that it would use the refresh token to go get a new access_token from Auth0 either whenever getTokenSilently() was invoked or by tracking the access_token expiration and automatically going to Auth0 to fetch an updated one (using the web worker). What triggers the use of the refresh token by auth0-spa-js and if getTokenSilently() will not force it, is there another method that can be called to force the silent refresh?
Follow up:
I was able to discover that the calls to /oauth/token with the refresh token are occurring but the response is missing the id_token and scope fields. I am getting a new access_token and refresh_token in the response. What could be causing that? I saw a post mentioning that the original token must have included the openid scope and it does. Any other common reasons that the scope and id_token would be missing in the response to /oauth/token during refresh?
Not sure why this post was marked as the solution. I’m still wondering why the id_token isn’t being returned automatically as it is described in documentation. Looking at the code, I don’t see a way to force the call to oauth/token to contain the openid scope which would result in it properly sending back the id_token. Is this a bug somewhere either in Auth0 token service or the auth0-spa-js?
For others that run into this problem, here was my solution.
I had a rule that ensured that there weren’t any scopes requested that hadn’t been authorized. It was modeled after the example here.
When a request to refresh the access_token comes in from the auth0-spa-js library, it won’t have any scopes defined. Because my rule sent back an empty string for scope in that scenario, it was causing the id_token to be left off the response. Here is my final code for the rule that includes a workaround to add the proper scopes on when a refresh request comes in: