NextAuth 4.x凭证登录:如何将isAdmin字段加入JWT会话
解决Next-Auth JWT会话中无法获取isAdmin属性的问题
问题核心在于JWT策略下,Next-Auth不会自动将用户的自定义属性同步到token和会话中,需要手动在jwt和session回调里完成属性传递。以下是具体修复步骤:
1. 修改jwt回调,将isAdmin存入token
登录时(user参数存在),把用户的isAdmin属性添加到JWT token中:
async jwt({ token, user, account, profile, isNewUser }) { // 仅在首次登录时(user存在)注入自定义属性 if (user) { token.isAdmin = user.isAdmin; // 可选:同步用户ID等其他需要的属性 token.id = user._id; } return token; },
2. 修改session回调,将token中的isAdmin同步到会话
把token里的isAdmin赋值给会话对象的user属性,确保前端能通过useSession()获取:
async session({ session, user, token }) { // 将token中的属性传递给会话对象 session.user.isAdmin = token.isAdmin; session.user.id = token.id; return session; },
额外优化:确保authorize返回普通对象(可选)
如果你的User是Mongoose文档对象,可能存在部分属性不可枚举的情况,建议在authorize里返回普通JS对象:
if (isValid) { // 转成普通对象,确保所有属性能被Next-Auth读取 return user.toObject(); }
修改后的完整配置代码
import NextAuth from "next-auth"; import CredentialsProvider from "next-auth/providers/credentials"; import User from "../../../../models/User"; export const authOptions = { secret: process.env.NEXTAUTH_SECRET, session: { strategy: "jwt" }, providers: [ CredentialsProvider({ name: "Credentials", credentials: { username: { label: "Username", type: "text", placeholder: "jsmith@domain.com", }, password: { label: "Password", type: "password" }, }, async authorize(credentials, req) { try { const user = await User.findOne({ email: credentials.username, }).exec(); if (user) { const isValid = await user.comparePassword(credentials.password); if (isValid) { // 转换为普通对象返回 return user.toObject(); } } return null; } catch (err) { console.log(err); } }, }), ], callbacks: { async signIn({ user, account, profile, email, credentials }) { return true; }, async redirect({ url, baseUrl }) { return baseUrl; }, async jwt({ token, user, account, profile, isNewUser }) { if (user) { token.isAdmin = user.isAdmin; token.id = user._id; } return token; }, async session({ session, user, token }) { session.user.isAdmin = token.isAdmin; session.user.id = token.id; return session; }, }, pages: { signIn: "/auth/signin", signOut: "/auth/signout", error: "/auth/error", verifyRequest: "/auth/verify-request", newUser: "/auth/register", }, }; const handler = NextAuth(authOptions); export { handler as GET, handler as POST };
完成以上修改后,你就能在前端通过useSession()获取到包含isAdmin属性的用户会话数据了。
内容的提问来源于stack exchange,提问作者rsilva
相关产品推荐
相关产品推荐

