使用NextAuth Credentials登录后Session仅含用户邮箱的原因及解决
问题:NextAuth CredentialsProvider登录后Session仅返回邮箱,无法获取firstName、lastName等字段?
原因分析
你使用了jwt作为session存储策略,NextAuth默认只会从authorize返回的用户对象中提取email这类标准字段存入JWT,不会自动包含firstName、lastName、phoneNumber、_id这些自定义字段,因此前端通过useSession只能拿到默认的邮箱信息。
解决方案
需要在authOptions中添加jwt和session两个回调函数,手动将需要的用户字段注入到JWT和Session中。修改后的完整配置代码如下:
import NextAuth from "next-auth" import CredentialsProvider from "next-auth/providers/credentials" import { connectToDb } from "@utils/database" import User from "@models/user" import bcrypt from "bcrypt" export const authOptions = { providers: [ CredentialsProvider({ name: "credentials", credentials: { email: { label: "Email", type: "email", placeholder: ""}, password: { label: "Password", type: "password", placeholder: ""} }, async authorize(credentials) { const {email, password} = credentials try { await connectToDb() const user = await User.findOne({ email }) if(!user) { return null } const passwordsMatch = await bcrypt.compare(password, user.password) if(!passwordsMatch) { return null } // 明确返回需要传递的用户字段,排除敏感的password return { id: user._id.toString(), email: user.email, firstName: user.firstName, lastName: user.lastName, phoneNumber: user.phoneNumber } } catch (error) { console.log(error) return null } } }) ], session: { strategy: "jwt", }, // 添加回调函数自定义JWT和Session内容 callbacks: { async jwt({ token, user }) { // 用户登录时,将自定义字段附加到JWT token if (user) { token.id = user.id token.firstName = user.firstName token.lastName = user.lastName token.phoneNumber = user.phoneNumber } return token }, async session({ session, token }) { // 将JWT中的字段映射到Session对象,供前端获取 if (session.user) { session.user.id = token.id session.user.firstName = token.firstName session.user.lastName = token.lastName session.user.phoneNumber = token.phoneNumber } return session } }, secret: process.env.NEXTAUTH_SECRET, pages: { signIn: '/login' } } const handler = NextAuth(authOptions) export { handler as GET, handler as POST}
关键说明:
- authorize函数优化:返回用户对象时明确指定需要传递的字段,避免返回敏感的
password,确保后续回调能拿到目标数据。 - jwt回调:在用户首次登录时,将自定义字段添加到JWT token中,让token存储完整的用户信息。
- session回调:把JWT中的字段映射到
session.user,前端通过useSession就能获取到所有需要的用户字段。
修改完成后重启项目,Dashboard页面打印的session就会包含firstName、lastName、phoneNumber、id等字段了。
内容的提问来源于stack exchange,提问作者Cip
相关产品推荐
相关产品推荐

