Next-auth: Unable to set accessToken in signIn callback

Created on 1 Dec 2020  路  6Comments  路  Source: nextauthjs/next-auth

Your question
Unable to set accessToken in signIn callback

What are you trying to do
I'm trying to add an accessToken to the session object coming from a custom backend.
When the user signs in we fetch an accessToken from a custom backend in the signIn callback.
Still in the signIn callback we set the accessToken on the user user.accessToken = data.authToken.

In the jwt callback we check for a user, if present we add the accessToken from the user - at this stage we do not have the fetched accessToken anymore as a result we can't access it in the session either.

  callbacks: {
    signIn: async (user: CurrentUser, account) => {
      try {
        const response = await fetch(
          `${SERVER_URL}/api/account/auth-token?accountId=${account.id}`,
        );
        if (!response.ok) {
          throw new Error('Failed to generate token.');
        }
        const data = await response.json();
        user.accessToken = data.authToken;
        return Promise.resolve(true);
      } catch (error) {
        return Promise.reject('/');
      }
    },
    jwt: async (token, user: CurrentUser) => {
      if (user) {
        token = {
          id: user.id,
          accessToken: user.accessToken || 'NO TOKEN FOUND',
        };
      }
      return Promise.resolve(token);
    },
    session: async (session: Session, token: any) => {
      session.accessToken = token.accessToken;
      session.user.id = token.id;
      return Promise.resolve(session);
    },
  },

Feedback
I followed the referred to example but to no avail. Is it possible the referred to document is outdated and this is no longer possible? Staring at it for quite a while, am I missing something obvious? Thanks in advance!

  • [x] Found the documentation helpful
  • [x] Found documentation but was incomplete
  • [ ] Could not find relevant documentation
  • [x] Found the example project helpful
  • [ ] Did not find the example project helpful
question

All 6 comments

Hi there!

You could fetch the access token in the jwt callback as well. In addition to user, you will also get the account in jwt, if it's the first time jwt is called.
It's the third parameter. 馃檪

From your example, it looks like you only need the account ID. I am curious though, do you take other measures to get hold of an access token besides sending an account ID? please prove me wrong but from your code example, it looks like I could get an excess token for a user, if I know their ID.

A standard way of getting an access token is using OAuth authorization flow, which next-auth supports out of the box, if your Identity Provider is OAuth compliant.

Relevant documentation:

https://auth0.com/docs/flows/authorization-code-flow (example)

https://next-auth.js.org/configuration/callbacks#jwt-callback

Hi,

Thanks already, getting the token in the jwt callback indeed works.

No that's still a big flaw, Azure AD B2C is being used.
I guess following these docs I should be able to retrieve the access tokens.

Thanks!

https://docs.microsoft.com/en-us/azure/active-directory-b2c/authorization-code-flow#2-get-an-access-token
Looking at this, you can actually configure next-auth to receive your token at sign-in automatically.

You should be able to configure it with a custom provider's accesstoken url https://next-auth.js.org/configuration/providers#using-a-custom-provider

Keep an eye on #809 ;)

Great to hear that this'll be a built-in provider! 馃憦

At the moment my custom provider works like a charm, except getting the accessToken doesn't seem to work yet.
I presume this should be returned in the account?
Current example of what gets returned

account: { provider: 'azureb2c', type: 'oauth', id: '10299'-3904...., refreshToken: 'eyJr.....', accessToken: undefined, accessTokenExpires: null },

I'll go over the steps again , probably missed something.

Provider:

    {
      id: 'azureb2c',
      name: 'Azure B2C',
      type: 'oauth',
      version: '2.0',
      scope: 'offline_access openid',
      params: {
        grant_type: 'authorization_code',
      },
      accessTokenUrl: `https://${TENANT_NAME}.b2clogin.com/${TENANT_NAME}.onmicrosoft.com/oauth2/v2.0/token?p=${USER_FLOW}`,
      authorizationUrl: `https://${TENANT_NAME}.b2clogin.com/${TENANT_NAME}.onmicrosoft.com/oauth2/v2.0/authorize?p=${USER_FLOW}&nonce=defaultNonce&response_type=code+id_token&prompt=login&response_mode=form_post`,
      profileUrl: 'https://graph.microsoft.com/oidc/userinfo',
      profile: (profile) => {
        return {
          id: profile.oid,
          firstName: profile.given_name,
          lastName: profile.family_name,
          email: profile?.emails?.[0],
        };
      },
      clientId: CLIENT_ID,
      clientSecret: CLIENT_SECRET,
      idToken: true,
      state: false,
    },
  session: {
    jwt: true,
  },
  jwt: {
    secret: JWT_SECRET,
  },

You can try adding debug: true to your NextAuth config, for a more verbose logging, maybe it will be easier to detect where the accessToken disappears. If it is there at a point, it means the token gets lost in NextAuth, in that case it is a bug.

If you are comfortable with the OAUTH spec, you can try re-playing the steps of an authentication from Postman, and see that the access_token actually gets sent where it needs to be, or is it a configuration issue in your Azure setup. If that is the case, the error is not in next-auth.

Jep the debug is very helpful, I'm not getting the accessToken back at all from azure.
The problem of not getting the accessToken back is referenced in this issue as well. So as far as I'm concerned this issue can be closed.
Big thanks already!

Was this page helpful?
0 / 5 - 0 ratings