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

Next-Auth第三方登录时如何将自定义角色与ID存入Session?

解决NextAuth第三方登录(Google)自定义字段存入Session的问题

你的问题核心在于第三方登录时,jwt回调无法获取到数据库中用户的_id、admin、banned字段——默认第三方登录返回的user对象只包含基础信息(如name、email),没有你自定义的字段。以下是具体修复步骤:

1. 修改signIn回调:传递数据库完整用户信息

在signIn回调中,无论用户是首次注册还是已存在,都要从数据库取出完整的用户文档,并将自定义字段附加到user对象中,确保后续jwt回调能拿到这些数据:

async signIn({ user }) {
  await db.connect();
  let dbUser = await Users.findOne({ email: user?.email });

  // 首次登录:创建用户并获取新文档
  if (!dbUser) {
    try {
      const userSchema = {
        name: user?.name || '',
        email: user?.email || '',
        password: 'Signed using google',
        picture: profilePictures[Math.floor(Math.random()*profilePictures.length)].path || '/images/TpAnime.jpg',
        bookMark: { animeList: [], watchList: [] },
        banned: false,
        admin: false,
      };
      dbUser = await Users.create(userSchema);
    } catch (err) {
      throw new Error("Something Went Wrong!, Try Signing With Another Account.");
    }
  }

  // 将数据库用户的自定义字段附加到user对象
  user._id = dbUser._id;
  user.admin = dbUser.admin;
  user.banned = dbUser.banned;
  
  await db.disconnect();
  return true; // 允许登录
}

2. 优化jwt回调:确保字段正确存入Token

修改后的jwt回调会在首次登录时,从已注入自定义字段的user对象中提取信息存入Token,后续Token刷新时也能保留这些字段:

async jwt({ token, user }) {
  // 首次登录(user存在时),存入自定义字段
  if (user) {
    token._id = user._id;
    token.admin = user.admin;
    token.banned = user.banned;
  }
  // 可选:后续Token刷新时,同步数据库最新的权限状态
  // if (token.email) {
  //   const dbUser = await Users.findOne({ email: token.email });
  //   token.admin = dbUser.admin;
  //   token.banned = dbUser.banned;
  // }
  return token;
}

3. 保持session回调不变

你的session回调已经正确将Token中的字段映射到Session,无需修改:

async session({ session, token }) {
  if (token?._id) session.user._id = token._id;
  if (typeof token?.admin === "boolean") session.user.admin = token.admin;
  if (typeof token?.banned === "boolean") session.user.banned = token.banned;
  return session;
}

关键原理说明

  • 第三方登录时,signIn回调是唯一能将用户身份与数据库关联的环节,必须在这里把自定义字段注入到user对象中。
  • jwt回调在首次登录时会收到user参数,此时将自定义字段存入Token,后续每次请求都会从Token中读取这些字段,最终通过session回调传递给前端。

内容的提问来源于stack exchange,提问作者Viper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 00:17:04