how to get Azure AD refresh token in Next-Auth / Auth.js

189 Views Asked by At

have been looking for 2 days how to get the refresh token, with this configuration, but in response refresh token is missing.

want to get new refresh token automatically so user not have to sign in again.

import NextAuth, { NextAuthOptions } from "next-auth";
import AzureADProvider from "next-auth/providers/azure-ad";

export const authOptions: NextAuthOptions = {
  providers: [
    AzureADProvider({
      clientId: `${process.env.AZURE_AD_CLIENT_ID}`,
      clientSecret: `${process.env.AZURE_AD_CLIENT_SECRET}`,
      tenantId: process.env.AZURE_AD_TENANT_ID,
      authorization: {
        params: {
          scope:
            "offline_access openid profile email Application.ReadWrite.All Directory.ReadWrite.All " +
            "Group.ReadWrite.All GroupMember.ReadWrite.All User.Read User.ReadWrite.All",
        },
      },
    }),
  ],
  callbacks: {
    async jwt({ token, user, account, profile }) {
      // Persist the OAuth access_token to the token right after signin

      console.log("JWT token", token);

      if (account) {
        console.log("account", token);
        token.accessToken = account.access_token;
      }
      return token;
    },
  },
};

This is the response i get

JWT token {
  name: 'name',
  picture: null,
  sub: 'X6_CatcEVmqbZlsN91oFDhdV3QUVe-....',
  accessToken: 'token',
  iat: 1708110693,
  exp: 1710702693,
  jti: '8eb36962-5998-4950-b0c9-7...'
}
1

There are 1 best solutions below

2
Sridevi On BEST ANSWER

I registered one Entra ID application and granted below API permissions based on your scopes:

enter image description here

Now, I added http://localhost:3000/api/auth/callback/azure-ad as redirect URI in Web platform:

enter image description here

Initially, I too got same results without refresh token when I ran your code in my environment:

import { NextAuthOptions } from 'next-auth'
import AzureADProvider from 'next-auth/providers/azure-ad'

export const authOptions: NextAuthOptions = {
  providers: [
    AzureADProvider({
      clientId: `${process.env.AZURE_AD_CLIENT_ID}`,
      clientSecret: `${process.env.AZURE_AD_CLIENT_SECRET}`,
      tenantId: process.env.AZURE_AD_TENANT_ID,
      authorization: {
        params: {
          scope: 'offline_access openid profile email Application.ReadWrite.All Directory.ReadWrite.All ' +
            'Group.ReadWrite.All GroupMember.ReadWrite.All User.Read User.ReadWrite.All',
        },
      },
    }),
  ],

callbacks: {
  async jwt({ token, user, account, profile }) {
    // Persist the OAuth access_token to the token right after signin

    console.log("JWT token", token);

    if (account) {
      console.log("account", token);
      token.accessToken = account.access_token;
    }
    return token;
  },
},
};

enter image description here

When I ran below modified code and logged in again with same account, I got the refresh token in response successfully like this:

import { NextAuthOptions } from 'next-auth'
import AzureADProvider from 'next-auth/providers/azure-ad'

let accountInfoProcessed = false;

export const authOptions: NextAuthOptions = {
  providers: [
    AzureADProvider({
      clientId: `${process.env.AZURE_AD_CLIENT_ID}`,
      clientSecret: `${process.env.AZURE_AD_CLIENT_SECRET}`,
      tenantId: process.env.AZURE_AD_TENANT_ID,
      authorization: {
        params: {
          scope: 'offline_access openid profile email Application.ReadWrite.All Directory.ReadWrite.All ' +
            'Group.ReadWrite.All GroupMember.ReadWrite.All User.Read User.ReadWrite.All',
        },
      },
    }),
  ],

  callbacks: {
    async jwt({ token, account }) {
      // Persist the OAuth access_token to the token right after signin

      // Process account info only if it hasn't been processed before
      if (account && !accountInfoProcessed) {
        console.log("Account Info:", account);
        token.accessToken = account.access_token;
        token.refreshToken = account.refresh_token;
        console.log("Refresh Token:", token.refreshToken);

        // Set the flag to true to indicate that account info has been processed
        accountInfoProcessed = true;
      }
      return token;
    },
  },
};

enter image description here

In your case, make sure to grant offline_access permission in your application and sign in again with modified code to get refresh token.

References:

next.js - NextAuth refresh token with Azure AD - Stack Overflow

javascript - Missing Azure AD refresh token in Next-Auth / Auth.js - Stack Overflow