NextJS中getServerSideProps无法将session传递至组件
解决Next.js中getServerSideProps传递session为undefined的问题
问题描述
在Next.js项目中,我在getServerSideProps里通过requireAuthentication函数获取了包含userId的session对象,控制台能正常打印该session,但将其作为props传递给页面组件后,组件内打印session却显示undefined,其他props(如secret)能正常接收。
相关代码
页面组件代码
const DashboardPage = ({ session, secret }) => { const [loading, setloading] = useState(false); // 此处打印session为undefined console.log('Session: ', session); return ( <section className="border-4 border-orange-800 max-w-5xl mx-auto"> <CreateListModal userId={session?.userId} loading={loading} setloading={setloading} /> </section> ) } export const getServerSideProps = async context => { // 获取添加了userId的session对象 const session = await requireAuthentication(context); // 此处能正常打印session console.log(session); if (!session) { return { redirect: { destination: '/signup', permanent: false } } } else { return { props: { session: session, secret: 'Pasarika este dulce' } } } } export default DashboardPage;
requireAuthentication函数代码
import { getSession } from "next-auth/react"; import prisma from './prisma' // 该函数获取邮箱并返回包含userId的新session对象 export const requireAuthentication = async context => { const session = await getSession(context); // 若无用户或出错则返回登录页面 if (!session) return null else { try { const user = await prisma.user.findUnique({where: { email: session.user.email }}); if (!user) return null; const newSession = { user: { ...session.user, userId: user.id }, expires: session.expires }; return newSession; } catch (error) { if (error) { console.log(error); } } } }
返回的session结构示例
{ "user": { "name": "daniel sas", "email": "email@gmail.com", "image": "https://lh3.googldeusercontent.com/a/A6r44ZwMyONqcfJORNnuYtbVv_LYbab-wv5Uyxk=s96-c", "userId": "clbcpc0hi0002sb1wsiea3q5d" }, "expires": "2022-12-23T08:04:08.263Z" }
问题原因及解决方案
核心原因
在服务器端的getServerSideProps中使用了客户端的getSession方法(来自next-auth/react),该方法主要用于客户端环境,在服务器端调用会导致session获取或序列化异常,最终传递到组件时变为undefined。
修复步骤
- 替换服务器端session获取方法
使用NextAuth提供的服务器端方法getServerSession替代getSession,并传入NextAuth的配置选项:
import { getServerSession } from "next-auth/next"; import { authOptions } from "../pages/api/auth/[...nextauth]"; // 替换为你的auth配置文件路径 import prisma from './prisma' export const requireAuthentication = async context => { // 通过getServerSession在服务器端获取session const session = await getServerSession(context.req, context.res, authOptions); if (!session) return null try { const user = await prisma.user.findUnique({where: { email: session.user.email }}); if (!user) return null; const newSession = { user: { ...session.user, userId: user.id }, expires: session.expires }; return newSession; } catch (error) { console.log(error); return null; // 异常时明确返回null,确保进入登录跳转逻辑 } }
确保props可序列化
检查返回的newSession是否包含不可序列化内容(如函数、Symbol等),当前session结构均为可序列化的基础类型,无需额外处理。验证组件props接收
确认页面组件接收props的变量名拼写正确(如session而非Session),当前代码的接收方式是正确的。
完成以上修改后,组件内即可正常接收并打印session对象。
内容的提问来源于stack exchange,提问作者daniel sas
相关产品推荐
相关产品推荐

