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

Next.js 15+NextAuth 5中服务端/客户端组件获取会话信息

NextAuth 5 + Next.js 15 无法获取会话用户邮箱的解决方案

核心问题排查

  1. JWT会话策略缺少关键回调:用jwt作为会话策略时,没配置jwt和session回调,导致用户邮箱没被存入令牌和会话对象
  2. 服务端会话获取方法错误:NextAuth 5 弃用了getServerSession直接传配置的用法,得用新的auth()函数
  3. 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;

验证方法

  1. 重启开发服务器
  2. 登录账号后,检查页面是否正常显示用户邮箱
  3. 调用/api/auth/session接口,确认返回的JSON中包含user.email字段

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 08:43:13