Next.js 15+NextAuth 5中服务端/客户端组件获取会话信息
NextAuth 5 + Next.js 15 无法获取会话用户邮箱的解决方案
核心问题排查
- JWT会话策略缺少关键回调:用
jwt作为会话策略时,没配置jwt和session回调,导致用户邮箱没被存入令牌和会话对象 - 服务端会话获取方法错误:NextAuth 5 弃用了
getServerSession直接传配置的用法,得用新的auth()函数 - SessionProvider 会话传递逻辑混乱:页面组件自己调用客户端
getSession再传给RootLayout,服务器组件里这么用会失效
分步修复方案
1. 补全JWT与Session回调
在NextAuth配置中添加回调,把用户邮箱存入JWT并同步到会话:
// auth.ts import NextAuth from 'next-auth'; import { authConfig } from './auth.config'; import Credentials from 'next-auth/providers/credentials'; // ...其他导入 export const { auth, signIn, signOut } = NextAuth({ ...authConfig, providers: [ Credentials({ async authorize(credentials) { // 保留你原本的验证逻辑 const parsedCredentials = z .object({ email: z.string().email(), password: z.string().min(6) }) .safeParse(credentials); if (parsedCredentials.success) { const { email, password } = parsedCredentials.data; const user = await getUser(email); if (!user) return null; const passwordsMatch = await bcrypt.compare(password, user.password); if (passwordsMatch) return user; } console.log('无效凭证'); return null; }, }), ], session: { strategy: 'jwt' }, pages: { signIn: '/auth/signin', }, // 新增这两个回调 callbacks: { async jwt({ token, user }) { // 用户登录时,把数据库里的邮箱存入token if (user) token.email = user.email; return token; }, async session({ session, token }) { // 把token里的邮箱同步到会话对象 if (session.user) session.user.email = token.email as string; return session; }, // 保留原有的authorized回调 ...authConfig.callbacks, }, });
2. 修正服务端会话接口
用NextAuth 5提供的auth()函数替代旧的getServerSession:
// app/api/auth/session/route.ts import { auth } from '@/auth'; import { NextResponse } from 'next/server'; export async function GET() { const session = await auth(); if (session) { return NextResponse.json(session); } else { return NextResponse.json({ error: '无有效会话' }, { status: 401 }); } }
3. 修复RootLayout与页面组件的会话传递
- RootLayout作为服务器组件,直接通过
auth()获取会话,再传给SessionProvider:
// app/layout.tsx import '@/app/ui/global.css'; import { SessionProvider } from 'next-auth/react'; import { auth } from '@/auth'; export default async function RootLayout({ children, }: { children: React.ReactNode; }) { const session = await auth(); return ( <html lang="zh-CN"> <body> <SessionProvider session={session}> {children} </SessionProvider> </body> </html> ); }
页面组件选择以下两种方式之一获取会话:
方案一(服务器组件直接获取):// app/page.tsx import { auth } from '@/auth'; export default async function Page() { const session = await auth(); return ( <div>用户邮箱:{session?.user?.email}</div> ); }方案二(客户端组件用钩子):
// app/page.tsx 'use client'; import { useSession } from 'next-auth/react'; export default function Page() { const { data: session } = useSession(); return ( <div>用户邮箱:{session?.user?.email}</div> ); }
4. 统一登录页面路径
确保auth.config.ts里的signIn路径和auth.ts一致:
// auth.config.ts import type { NextAuthConfig } from 'next-auth'; export const authConfig = { pages: { signIn: '/auth/signin', // 和auth.ts中的配置保持一致 }, callbacks: { // 保留原有的authorized逻辑 authorized({ auth, request: { nextUrl } }) { const isLoggedIn = !!auth?.user; const isOnDashboard = nextUrl.pathname.startsWith('/dashboard'); if (isOnDashboard) { if (isLoggedIn) return true; return false; } else if (isLoggedIn) { return Response.redirect(new URL('/dashboard', nextUrl)); } return true; }, }, providers: [], } satisfies NextAuthConfig;
验证方法
- 重启开发服务器
- 登录账号后,检查页面是否正常显示用户邮箱
- 调用
/api/auth/session接口,确认返回的JSON中包含user.email字段
内容的提问来源于stack exchange,提问作者kendra takam
相关产品推荐
相关产品推荐

