AccessTokenError when requesting offline_access scope

I came across this thread with a very similar issue and I’m still confused:

If I have this in pages/api/auth/[...auth0].ts

export default handleAuth({
  async login(req, res) {
    try {
      await handleLogin(req, res, {
        authorizationParams: {
          audience: 'https://[redacted]', // or AUTH0_AUDIENCE
          // Add the `offline_access` scope to also get a Refresh Token
          scope: 'openid profile email offline_access do:anything' // or AUTH0_SCOPE
    } catch (error) {
      res.status(error.status || 400).end(error.message);

And then later inside a getServerSideProps call

const { accessToken} = await getAccessToken(context.req, context.res, {
    scopes: ['openid', 'profile', 'email', 'offline_access', 'do:anything']

I get this error

AccessTokenError: Could not retrieve an access token with scopes "openid profile email offline_access do:anything". The user will need to sign in again.

But if I remove the scopes parameter above, it works AND the server indicates that the JWT has scope: 'openid profile email do:anything'. Note that my custom do:anything scope is there, but offline_access is missing.

Can someone help me understand what’s going on and which scopes should be used in which calls? Thanks!

Hi @jsw,

I went ahead and moved your reply to its own topic with a reference to the original topic for better visibility for your question.

I see that you are specifying an audience. Is the audience your own custom API? If so, is it configured to allow offline access?

Also, within your SPA’s application settings, do you have Refresh Token rotation enabled?

1 Like

@stephanie.chamblee The audience is a custom API, which I had not configured offline access. I also updated the application to enable Refresh Token Rotation. Now it seems to work, but I still have a remaining question… The call to getAccessToken in GetServerSideProps doesn’t seem to matter whether I specify scopes or not. In both cases, the server is confirming that the access token has all the scopes that were requested via handleLogin in [....auth0].ts. Can you help me understand the purpose of the scopes provided to handleAuth vs getAccessToken? Thanks!

Hi @jsw,

I’m glad to hear refresh tokens are working now!

The getAccessTokenSilently method will return the same Access Token that was obtained during login so long as it is still valid. It will only request a new token if the Access Token in memory has expired or if a different scope or audience is requested.

The scopes are optional in this method and if not passed, the same scopes will be used that are configured in handleAuth.

Here are the docs on this method: AuthService | @auth0/auth0-angular

Hi @stephanie.chamblee

I am using auth0/nextjs-auth0, not @auth0/auth0-angular, but I assume what you said about getAccessTokenSilently applies equivalently to getAccessToken in the NextJS module.

Yes, that is correct, both SDKs should behave the same in that regard.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.