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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 17:53:14