NextAuth会话无用户数据求助:登录后session未返回用户信息
NextAuth登录后Session无用户信息问题解决方案
问题描述
登录操作完成后,session数据中未包含用户信息。数据库中可查询到对应用户,且在authorize函数中通过console.log能正常输出用户对象,但session里始终没有用户数据。
相关代码
NextAuth配置文件
import User from "@/utils/user-Schema"; import NextAuth, { AuthOptions } from "next-auth" import CredentialsProvider from "next-auth/providers/credentials"; export const authOptions: AuthOptions = { providers: [ CredentialsProvider({ name: "credentials", credentials: { username: { label: "username", type: "text" }, password: { label: "password", type: "password" } }, async authorize(credentials) { try { const foundUser = await User.findOne({ username: credentials?.username}) if(foundUser && foundUser.password === credentials?.password) { return foundUser } } catch(e) { console.error(e) } return null } }) ], session: { strategy: "jwt" }, secret: process.env.SECRET, pages: { signIn: "/login" } } const handler = NextAuth(authOptions) export { handler as GET, handler as POST}
provider.tsx代码
"use client" import { SessionProvider as NextAuthSessionProvider } from "next-auth/react"; import { ReactNode } from "react"; type SessionProviderProps = { children: ReactNode; }; export default function SessionProvider({ children }: SessionProviderProps) { return ( <NextAuthSessionProvider> {children} </NextAuthSessionProvider> ); }
问题原因
当使用jwt作为session策略时,NextAuth不会自动将authorize函数返回的完整用户对象同步到JWT和session中;另外,authorize返回的是Mongoose文档对象,而非普通JavaScript对象,可能存在序列化问题导致部分信息无法被正确存储。
解决方案
在authOptions中添加jwt和session回调函数,手动指定要存入JWT和session的用户信息,同时将Mongoose文档转换为普通对象:
修改后的NextAuth配置
import User from "@/utils/user-Schema"; import NextAuth, { AuthOptions } from "next-auth" import CredentialsProvider from "next-auth/providers/credentials"; export const authOptions: AuthOptions = { providers: [ CredentialsProvider({ name: "credentials", credentials: { username: { label: "username", type: "text" }, password: { label: "password", type: "password" } }, async authorize(credentials) { try { const foundUser = await User.findOne({ username: credentials?.username}) if(foundUser && foundUser.password === credentials?.password) { // 将Mongoose文档转换为普通JS对象,避免序列化问题 return foundUser.toObject(); } } catch(e) { console.error(e) } return null } }) ], session: { strategy: "jwt" }, // 配置jwt回调,将需要的用户字段存入token jwt: { async token({ token, user }) { if (user) { // 按需添加需要的用户字段 token.id = user._id; token.username = user.username; } return token; } }, // 配置session回调,从token中提取信息到session callbacks: { async session({ session, token }) { if (token) { session.user = { id: token.id, username: token.username // 可添加其他需要展示的用户字段 }; } return session; } }, secret: process.env.SECRET, pages: { signIn: "/login" } } const handler = NextAuth(authOptions) export { handler as GET, handler as POST}
关键步骤说明
- 转换Mongoose文档:在
authorize中使用toObject()将查询到的用户文档转换为普通对象,避免序列化异常。 - 配置jwt回调:用户登录成功时,将需要的用户字段(如
id、username)存入JWT token。 - 配置session回调:从JWT token中提取用户信息,赋值给
session.user,确保前端能获取到完整的用户数据。
内容的提问来源于stack exchange,提问作者dandeib
相关产品推荐
相关产品推荐

