基于Credentials的NextAuth角色登录实现问题求助
解决NextAuth Credentials提供商角色字段无法传入Session的问题
你的问题出在JWT策略下的回调逻辑:
- 当使用
session: { strategy: "jwt" }时,session回调里的user参数是undefined——因为JWT策略下用户数据仅存储在Token中,不会传入session回调的user参数 - 你的
jwt回调未将role字段存入Token,导致后续无法读取该字段
修复步骤:
- 更新JWT回调,存入role字段
在jwt回调中,把用户的role也添加到token对象里:
jwt: ({ token, user }) => { if (user) { token.id = user.id; token.role = user.role; // 新增:将role存入token } return token; },
- 修改Session回调,从Token中读取role
放弃从user参数获取role,直接从token中读取并赋值给session.user:
session: ({ session, token }) => { if (token) { session.id = token.id; session.user.role = token.role; // 从token中读取role } return session; },
- 扩展NextAuth类型(TypeScript必填)
NextAuth默认类型不包含role字段,需在项目中添加类型声明文件(比如types/next-auth.d.ts)扩展类型:
import NextAuth from "next-auth"; declare module "next-auth" { interface User { role: string; } interface Session { id: string; user: { role: string; } & DefaultSession["user"]; } } declare module "next-auth/jwt" { interface JWT { id: string; role: string; } }
完整修复后的代码示例:
import NextAuth, { NextAuthOptions } from "next-auth"; import Credentials from "next-auth/providers/credentials"; const authOptions: NextAuthOptions = { providers: [ Credentials({ id: "credentials", name: "Credentials", credentials: {}, async authorize(credentials) { const { email, password } = credentials as { email: string; password: string; }; // 模拟数据库验证逻辑 if (email === "john@gmail.com" && password === "1234") { return { id: "1234", name: "John Doe", email: "john@gmail.com", role: "admin", }; } throw new Error("Invalid credentials"); }, }), ], callbacks: { jwt: ({ token, user }) => { if (user) { token.id = user.id; token.role = user.role; // 存入role到token } return token; }, session: ({ session, token }) => { if (token) { session.id = token.id; session.user.role = token.role; // 从token读取role } return session; }, }, session: { strategy: "jwt", }, pages: { signIn: "/login", }, secret: process.env.NEXT_PUBLIC_SECRET, }; export default NextAuth(authOptions);
补充说明:
- 无需自定义Adapter,Credentials提供商完全支持扩展用户字段,只要在JWT回调中把需要的字段存入Token即可
- 没必要用自定义JWT登录替代NextAuth,其自带的JWT策略已能满足需求,只需正确配置回调逻辑
内容的提问来源于stack exchange,提问作者Khoo Wing Hang
相关产品推荐
相关产品推荐

