Next.js 14中GET接口无法从Session获取用户ID问题
问题:NextAuth Session在API路由中丢失User ID导致地址查询返回空数组
问题现象
- 配置NextAuth时,
session回调的日志显示session.user包含id字段 - 但在
getAllAddresses的API路由中,通过getServerSession获取到的session.user仅包含name、email、image,缺少id - 最终执行
Address.find({ userID: session.user.id })时因id不存在返回空数组
原因分析
使用jwt作为Session策略时,Session数据是从JWT令牌解析而来。当前配置存在两个问题:
jwt回调仅将登录时的user对象赋值给token.user,未将id字段持久化存入JWTsession回调中临时添加的session.user.id不会同步到JWT,导致后续请求解析Session时无法获取到id
解决方案
1. 更新NextAuth配置,确保User ID存入JWT并同步到Session
修改api/auth/[...nextauth]/route.js中的callbacks部分:
callbacks: { async signIn({ profile, account }) { if (account.provider === 'google') { try { await connect() let user = await User.findOne({ email: profile.email }) if (!user) { user = await User.create({ email: profile.email, name: profile.name, avatar: profile.image, wishlist: [], cart: [], orders: [], products: [] }) } return user } catch (error) { console.log(error) } } return true }, async jwt({ token, user }) { // 登录时将用户ID存入token if (user) { token.id = user._id.toString() token.user = { ...token.user, id: user._id.toString() } } return token }, async session({ session, token }) { // 从token中取出ID赋值给session.user if (session.user) { session.user.id = token.id } return session } }
2. 修正API路由中getServerSession的调用
getServerSession需要传入NextAuth的配置才能正确解析Session,修改getAllAddresses的API路由代码:
import { getServerSession } from "next-auth/next"; import { authOptions } from "../auth/[...nextauth]/route"; // 导入NextAuth配置 import { NextResponse } from "next/server"; import Address from "@/models/Address"; // 根据实际模型路径调整 export async function GET(req) { try { // 传入authOptions获取完整Session const session = await getServerSession(authOptions); console.log('🚀 ~ GET ~ session:', session); if (!session || !session.user.id) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } const getAllAddresses = await Address.find({ userID: session.user.id }); return NextResponse.json({ success: true, data: getAllAddresses, }); } catch (error) { console.error('Error fetching user addresses:', error); return NextResponse.json({ error: 'Internal Server Error' }, { status: 500 }); } }
关键说明
- 使用JWT策略时,所有需要在Session中持久化的字段必须存入JWT令牌,否则后续请求无法获取
getServerSession必须传入NextAuth的配置参数,才能正确验证并解析包含自定义字段的Session
内容的提问来源于stack exchange,提问作者klng
相关产品推荐
相关产品推荐

