Next.js+NextAuth+Prisma认证正常但index.tsx获取session为undefined
问题原因及修复方案
1. authorize函数返回值不符合要求
你当前使用prisma.user.findMany()查询用户,该方法返回的是用户数组,而NextAuth的authorize函数要求返回单个用户对象,返回数组会导致JWT生成逻辑异常,session无法正常写入。
修复代码:
async authorize(credentials) { // 替换findMany为findFirst,返回单个用户对象 const user = await prisma.user.findFirst({ where: { email: credentials.email, password: credentials.password, }, }); // 匹配到用户返回对象,未匹配返回null return user ?? null; }
注:明文存储密码存在安全风险,生产环境建议使用bcrypt等加密方案处理密码存储和校验
2. useEffect依赖项配置错误
当前useEffect依赖项为空数组,只会在组件首次挂载时执行,此时useSession还处于加载状态(loading值为true),session默认就是undefined。需要将session和loading加入依赖项,等状态更新后再读取:
const [session, loading] = useSession(); React.useEffect(() => { // 加载完成后再打印session if (!loading) { console.log(session); } }, [session, loading]);
3. 缺失JWT和session同步回调
使用Credentials认证方式时,NextAuth默认不会自动把用户信息同步到JWT和session中,需要在[...nextauth].ts中添加回调配置:
export default NextAuth({ // 原有providers、pages等配置保持不变 callbacks: { // 登录时把用户信息写入JWT async jwt(token, user) { if (user) { token.id = user.id; token.email = user.email; // 可自行添加其他需要存储的用户字段 } return token; }, // 把JWT中的信息同步到返回给前端的session async session(session, token) { session.user.id = token.id; session.user.email = token.email; return session; } } });
可选补充:服务端预取session
如果页面是服务端渲染,可在index.tsx中添加getServerSideProps预取session,保证客户端首次加载就能拿到session:
import { getSession } from 'next-auth/client'; // 页面组件逻辑保持不变 export async function getServerSideProps(context) { const session = await getSession(context); return { props: { session } } }
内容的提问来源于stack exchange,提问作者Jumail
相关产品推荐
相关产品推荐

