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

NextAuth v4 Beta数据库会话:存储OneLogin OAuth登录返回的额外字段方法

解决方案

步骤1:自定义OneLogin Provider的profile回调

该回调负责将OneLogin返回的OAuthProfile字段转换为NextAuth可识别的用户结构,你可以直接在这一步完成字段映射和自定义字段初始化:

// 你的NextAuth配置文件,比如app/api/auth/[...nextauth]/route.ts
import NextAuth from "next-auth"
import OneLoginProvider from "next-auth/providers/onelogin"
import { MongoDBAdapter } from "@next-auth/mongodb-adapter"
import clientPromise from "@/lib/mongodb" // 替换为你自己的MongoDB连接实例导出路径

export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: MongoDBAdapter(clientPromise),
  providers: [
    OneLoginProvider({
      clientId: process.env.ONELOGIN_CLIENT_ID,
      clientSecret: process.env.ONELOGIN_CLIENT_SECRET,
      issuer: process.env.ONELOGIN_ISSUER,
      // 新增profile回调处理字段映射
      profile(profile) {
        return {
          id: profile.sub, // 必填,NextAuth要求的用户唯一标识
          name: profile.given_name, // 直接将given_name赋值给name字段
          email: profile.email, // 保留必填的邮箱字段
          family_name: profile.family_name, // 新增需要存储的额外字段
          preferred_username: profile.preferred_username, // 新增需要存储的额外字段
          auth_level: "user" // 新增默认权限字段
        }
      }
    })
  ],
})

步骤2:扩展MongoDB适配器支持存储自定义字段

默认MongoDB适配器只会写入NextAuth预设的标准字段(id/name/email/emailVerified/image),你需要重写createUser方法将自定义字段存入users集合:

// 在NextAuth配置文件中调整适配器配置
const baseAdapter = MongoDBAdapter(clientPromise)
const customAdapter = {
  ...baseAdapter,
  async createUser(user) {
    // 将所有自定义字段传入创建用户的逻辑
    return baseAdapter.createUser({
      ...user,
      family_name: user.family_name,
      preferred_username: user.preferred_username,
      auth_level: user.auth_level
    })
  }
}

// 替换原有adapter配置为自定义适配器
export const { handlers, auth, signIn, signOut } = NextAuth({
  adapter: customAdapter,
  // 剩余配置保持不变
  providers: [/* ... */]
})

步骤3:(可选)同步自定义字段到会话

如果需要在前端通过useSession()或服务端auth()方法拿到这些自定义字段,需要额外配置回调:

如果你使用JWT会话

export const { handlers, auth, signIn, signOut } = NextAuth({
  // 其他配置不变
  session: { strategy: "jwt" },
  callbacks: {
    async jwt({ token, user }) {
      // 首次登录时将用户字段存入token
      if (user) {
        token.family_name = user.family_name
        token.preferred_username = user.preferred_username
        token.auth_level = user.auth_level
      }
      return token
    },
    async session({ session, token }) {
      // 将token中的字段同步到session
      if (session.user) {
        session.user.family_name = token.family_name as string
        session.user.preferred_username = token.preferred_username as string
        session.user.auth_level = token.auth_level as string
      }
      return session
    }
  }
})

如果你使用数据库会话

export const { handlers, auth, signIn, signOut } = NextAuth({
  // 其他配置不变
  session: { strategy: "database" },
  callbacks: {
    async session({ session, user }) {
      // 直接从数据库查询到的user对象中取字段同步到session
      if (session.user) {
        session.user.family_name = user.family_name
        session.user.preferred_username = user.preferred_username
        session.user.auth_level = user.auth_level
      }
      return session
    }
  }
})

步骤4:(可选)TypeScript类型扩展

如果你的项目使用TypeScript,需要新增类型声明文件扩展NextAuth的内置类型,避免类型报错:

// types/next-auth.d.ts
import NextAuth from "next-auth"

declare module "next-auth" {
  interface User {
    family_name: string
    preferred_username: string
    auth_level: string
  }

  interface Session {
    user: User
  }
}

// 如果使用JWT会话还需要扩展JWT类型
declare module "next-auth/jwt" {
  interface JWT {
    family_name: string
    preferred_username: string
    auth_level: string
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 01:30:05