如何在Next-Auth中同步JWT令牌与会话的生命周期?
会话生命周期与JWT令牌的同步
问题:我正尝试同步JWT令牌与会话的生命周期,当前的实现方式如下,但始终得到默认的Cookie生命周期(一个月)。是否有办法实现二者的同步?还是只能通过设置maxAge来解决?使用的next-auth版本为^4.17.0。
问题原因
你当前仅在session回调中修改了session.expires字段,但NextAuth的会话Cookie有效期仍沿用默认的30天。要实现同步,需要让NextAuth生成的JWT、前端拿到的session对象、会话Cookie三者的有效期都和后端返回的JWT保持一致。
解决方案
修改你的NextAuth配置,做以下调整:
- 在
jwt回调中,将后端JWT的过期时间赋值给NextAuth的JWT的exp字段,确保NextAuth自身的JWT和后端JWT同时过期; - 在
session回调中,同步设置session.maxAge为后端JWT的剩余有效期; - 显式配置会话Cookie规则,确保其有效期动态对齐JWT。
修改后的完整代码
import NextAuth from 'next-auth/next'; import CredentialsProvider from 'next-auth/providers/credentials'; import jwtDecode from 'jwt-decode'; import axios from 'axios'; export default NextAuth({ session: { strategy: 'jwt', // 不再写死maxAge,改为从后端JWT动态获取 }, jwt: { secret: process.env.JWT_SECRET }, // 配置会话Cookie规则,不写死maxAge,由session.maxAge动态控制 cookies: { sessionToken: { name: `next-auth.session-token`, options: { httpOnly: true, sameSite: 'lax', path: '/', secure: process.env.NODE_ENV === 'production', } } }, providers: [ CredentialsProvider({ id: 'login', async authorize(credentials) { try { const token = await axios.post(`${process.env.BACK_API}auth/v1/token/`, { password: credentials?.password, username: credentials?.email }); if (token) { const { exp, user_id, user, roles } = jwtDecode(token.data.access); return { ...token.data, exp, user: { user_id, user, roles } }; } else { return null; } } catch (error) { throw new Error(error.message); } } }), CredentialsProvider({ id: 'signup', async authorize(credentials) { try { return await Auth.signup(credentials); } catch (error) { throw new Error(error.message); } } }) ], callbacks: { jwt: ({ token, user, account, profile, isNewUser }) => { if (user) { token.accessToken = user.access; token.t_exp = user.exp; token.user = user.user; // 将后端JWT的过期时间赋值给NextAuth的JWT,确保二者同时过期 token.exp = user.exp; // 计算剩余有效期(秒) const now = Math.floor(Date.now() / 1000); token.maxAge = user.exp - now; } return token; }, async session({ session, token, user }) { if (token) { const expDate = new Date(token.t_exp * 1000); session.expires = expDate.toISOString(); // 设置session的maxAge为后端JWT的剩余有效期 session.maxAge = token.maxAge; // 将用户信息和token同步到session session.user = token.user; session.accessToken = token.accessToken; } return session; } } });
说明
- 配置完成后,NextAuth的JWT、session对象、会话Cookie的有效期都会和后端返回的JWT保持一致,实现生命周期同步;
- 无需手动写死
maxAge,所有有效期从后端JWT的exp字段动态计算,适配不同的token过期规则。
内容的提问来源于stack exchange,提问作者xcplat
相关产品推荐
相关产品推荐

