You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于Credentials的NextAuth角色登录实现问题求助

解决NextAuth Credentials提供商角色字段无法传入Session的问题

你的问题出在JWT策略下的回调逻辑:

  • 当使用session: { strategy: "jwt" }时,session回调里的user参数是undefined——因为JWT策略下用户数据仅存储在Token中,不会传入session回调的user参数
  • 你的jwt回调未将role字段存入Token,导致后续无法读取该字段

修复步骤:

  1. 更新JWT回调,存入role字段
    在jwt回调中,把用户的role也添加到token对象里:
jwt: ({ token, user }) => {
  if (user) {
    token.id = user.id;
    token.role = user.role; // 新增:将role存入token
  }
  return token;
},
  1. 修改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;
},
  1. 扩展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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 07:01:28