Next.js 14组件中获取Session信息的正确实现方法咨询
适配Next.js 14 + Next Auth v5 Beta的Session获取方案
核心问题原因
你用的getServerSideProps是Pages Router专属API,在App Router环境下完全不支持,直接传递session会导致组件props类型不匹配,这就是报错的根源。以下是适配你当前技术栈的几种正确实现方式:
1. 先确认Next Auth v5的基础配置
确保你的auth.ts配置符合v5 Beta的规范,结合Prisma Adapter的示例如下:
// app/auth.ts import NextAuth from "next-auth"; import Credentials from "next-auth/providers/credentials"; import { PrismaAdapter } from "@next-auth/prisma-adapter"; import prisma from "./lib/prisma"; import bcrypt from "bcryptjs"; // 假设用bcrypt做密码验证 export const { auth, signIn, signOut, handlers } = NextAuth({ adapter: PrismaAdapter(prisma), providers: [ Credentials({ credentials: { email: { label: "邮箱", type: "email" }, password: { label: "密码", type: "password" }, }, async authorize(credentials) { if (!credentials?.email || !credentials?.password) return null; const user = await prisma.user.findUnique({ where: { email: credentials.email }, }); if (!user || !user.password) return null; const passwordMatch = await bcrypt.compare(credentials.password, user.password); return passwordMatch ? user : null; }, }), ], session: { strategy: "jwt" }, // 或选"database",根据需求决定 secret: process.env.NEXTAUTH_SECRET, }); // 扩展Session类型,适配你的用户模型 declare module "next-auth" { interface Session { user: { id: string; email: string; // 按需添加name、avatar等自定义字段 } & DefaultSession["user"]; } }
2. React Server Components(RSC)中获取Session
App Router下的组件默认是RSC,可直接在组件内部调用auth()获取session(无需传props):
// app/account/settings/page.tsx import { auth } from "@/app/auth"; import { redirect } from "next/navigation"; export default async function AccountSettings() { // 直接在服务器端获取session const session = await auth(); // 未登录时重定向到登录页 if (!session) redirect("/login"); return ( <div className="container"> <h1>账户设置</h1> <div className="user-info"> <p>当前登录邮箱:{session.user.email}</p> <p>用户ID:{session.user.id}</p> </div> {/* 这里添加设置表单,比如修改密码、个人信息等 */} </div> ); }
3. Client Components中获取Session
如果你的组件需要客户端交互(比如用useState、表单提交),需先标记为Client Component,再用useSession钩子:
第一步:在根Layout中配置SessionProvider
// app/layout.tsx import { SessionProvider } from "next-auth/react"; import { auth } from "./auth"; import type { Metadata } from "next"; export const metadata: Metadata = { title: "我的应用", description: "基于Next.js 14的项目", }; export default async function RootLayout({ children, }: { children: React.ReactNode; }) { // 从服务器端获取初始session,传给Provider const session = await auth(); return ( <html lang="zh-CN"> <body> <SessionProvider session={session}> {children} </SessionProvider> </body> </html> ); }
第二步:编写Client Component版本的AccountSettings
// app/account/settings/ClientSettings.tsx "use client"; import { useSession } from "next-auth/react"; import { useState } from "react"; export default function ClientSettings() { const { data: session, status } = useSession(); const [newPassword, setNewPassword] = useState(""); if (status === "loading") return <div>加载中...</div>; if (!session) return <div>请先登录</div>; const handlePasswordChange = async (e: React.FormEvent) => { e.preventDefault(); // 这里调用Server Action修改密码 }; return ( <div className="container"> <h1>账户设置(客户端交互版)</h1> <p>当前用户:{session.user.email}</p> <form onSubmit={handlePasswordChange}> <input type="password" value={newPassword} onChange={(e) => setNewPassword(e.target.value)} placeholder="输入新密码" required /> <button type="submit">修改密码</button> </form> </div> ); }
4. Server Actions中获取Session
在Server Actions里直接调用auth()即可拿到session,用于授权验证:
// app/actions/accountActions.ts "use server"; import { auth } from "@/app/auth"; import prisma from "@/app/lib/prisma"; import bcrypt from "bcryptjs"; export async function updateUserPassword(newPassword: string) { const session = await auth(); // 未授权时抛出错误 if (!session?.user.id) throw new Error("请先登录"); const hashedPassword = await bcrypt.hash(newPassword, 10); await prisma.user.update({ where: { id: session.user.id }, data: { password: hashedPassword }, }); }
内容的提问来源于stack exchange,提问作者Paca
相关产品推荐
相关产品推荐

