You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I recently implemented refresh token rotation into my Next.js webapp using Azure Active Directory (organizations version, not B2C). I used this official resource to do this, and slightly modified the code to my needs and to work with Azure AD instead of Google. However, it does not work.
During debugging, I found out that the function async function refreshAccessToken(token) works, i.e., the Graph API returns a new access token. However, it seems that somehow, this refreshed token is not passed to the async session({session, token}) callback, resulting in token to be undefined. This means that if a user navigates to an authenticated route 1+ hours after logging in, the error below appears in the Node.js console. Instead of passing the refreshed accessToken to the client-side, the user is forwarded to the signin page.
Error code
[next-auth][error][JWT_SESSION_ERROR]
https://next-auth.js.org/errors#jwt_session_error Cannot read properties of undefined (reading 'accessToken') {
message: "Cannot read properties of undefined (reading 'accessToken')",
stack: "TypeError: Cannot read properties of undefined (reading 'accessToken')\n" +
' at Object.session (webpack-internal:///(api)/./pages/api/auth/[...nextauth].ts:71:41)\n' +
' at Object.session (D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next-auth\\core\\routes\\session.js:56:42)\n' +
' at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n' +
' at async AuthHandler (D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next-auth\\core\\index.js:158:27)\n' +
' at async NextAuthHandler (D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next-auth\\next\\index.js:23:19)\n' +
' at async D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next-auth\\next\\index.js:59:32\n' +
' at async Object.apiResolver (D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next\\dist\\server\\api-utils\\node.js:363:9)\n' +
' at async DevServer.runApi (D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next\\dist\\server\\next-server.js:487:9)\n' +
' at async Object.fn (D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next\\dist\\server\\next-server.js:749:37)\n' +
' at async Router.execute (D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next\\dist\\server\\router.js:253:36)\n' +
' at async DevServer.run (D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next\\dist\\server\\base-server.js:384:29)\n' +
' at async DevServer.run (D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next\\dist\\server\\dev\\next-dev-server.js:741:20)\n' +
' at async DevServer.handleRequest (D:\\Programmeren\\Heatwaves\\heatwaves\\node_modules\\next\\dist\\server\\base-server.js:322:20)',
name: 'TypeError'
}
How to reproduce 鈽曪笍
[...nextauth] API endpoint
importNextAuthfrom"next-auth"importAzureADfrom"next-auth/providers/azure-ad";asyncfunctionrefreshAccessToken(accessToken){try{consturl="https://login.microsoftonline.com/02cd5db4-6c31-4cb1-881d-2c79631437e8/oauth2/v2.0/token"awaitfetch(url,{method: "POST",headers: {"Content-Type": "application/x-www-form-urlencoded",},body: `grant_type=refresh_token`+`&client_secret=${process.env.AZURE_AD_CLIENT_SECRET}`+`&refresh_token=${accessToken.refreshToken}`+`&client_id=${process.env.AZURE_AD_CLIENT_ID}`}).then(res=>res.json()).then(res=>{return{
...accessToken,accessToken: res.access_token,accessTokenExpires: Date.now()+res.expires_in*1000,refreshToken: res.refresh_token??accessToken.refreshToken,// Fall back to old refresh token}})}catch(error){console.log(error)return{
...accessToken,error: "RefreshAccessTokenError",}}}exportconstauthOptions={providers: [AzureAD({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: {asyncjwt({token, account, profile}){// Persist the OAuth access_token and or the user id to the token right after signinif(account&&profile){token.accessToken=account.access_token;token.accessTokenExpires=account.expires_at*1000;token.refreshToken=account.refresh_token;token.id=profile.oid;// For convenience, the user's OID is called ID.token.groups=profile.groups;token.username=profile.preferred_username;returntoken;}if(Date.now()<token.accessTokenExpires){returntoken;}returnrefreshAccessToken(token);},asyncsession({session, token}){// Send properties to the client, like an access_token and user id from a provider.session.accessToken=token.accessToken;session.user.id=token.id;session.user.groups=token.groups;session.user.username=token.username;constsplittedName=session.user.name.split(" ");session.user.firstName=splittedName.length>0 ? splittedName[0] : null;session.user.lastName=splittedName.length>1 ? splittedName[1] : null;returnsession;},},pages: {signIn: '/login',}}exportdefaultNextAuth(authOptions)
your refreshAccessToken never returns since you are using .then and no return on the fetch call. I would recommend against mixing await and Promises in general.
Question 馃挰
I recently implemented refresh token rotation into my Next.js webapp using Azure Active Directory (organizations version, not B2C). I used this official resource to do this, and slightly modified the code to my needs and to work with Azure AD instead of Google. However, it does not work.
During debugging, I found out that the function
async function refreshAccessToken(token)
works, i.e., the Graph API returns a new access token. However, it seems that somehow, this refreshed token is not passed to theasync session({session, token})
callback, resulting intoken
to beundefined
. This means that if a user navigates to an authenticated route 1+ hours after logging in, the error below appears in the Node.js console. Instead of passing the refreshed accessToken to the client-side, the user is forwarded to the signin page.Error code
How to reproduce 鈽曪笍
[...nextauth] API endpoint
Middleware (Next.js)
Azure AD dashboard
Below, I have an image of my Authentication page of my Azure AD app registration, might there be something wrong with that:
Contributing 馃檶馃徑
No, I am afraid I cannot help regarding this
The text was updated successfully, but these errors were encountered: