Auth.js v5数据库会话策略下Credential Provider返回Session为Null
问题排查与解决方案
核心原因推测
使用Credentials Provider时auth()返回null,大概率是会话未被Auth.js正确创建或关联——因为其他OAuth Provider(Google/Github)功能正常,说明Auth.js基础配置和Prisma适配器是没问题的,问题出在Credentials Provider的专属流程里。
具体排查与修复步骤
1. 移除自定义的generateSessionToken调用
你的authorize函数里手动调用了await generateSessionToken(user.id),但在Database会话策略下,Auth.js会自动完成会话创建、令牌生成和Cookie设置的完整流程,手动干预反而可能破坏这个流程,导致会话无法正确关联到用户。
修改后的authorize函数:
async authorize(credentials) { const validate = loginSchema.safeParse(credentials) if (!validate.success) return null const { email, password } = validate.data const user = await getUserByEmail(email) if (!user || !user.password) { return null } const passwordmatch = await bcrypt.compare(password, user.password) if (passwordmatch) { // 移除手动生成会话的代码,交由Auth.js自动处理 // await generateSessionToken(user.id) return user } return null },
2. 验证数据库会话记录是否生成
登录后检查Vercel Postgres的sessions表:
- 确认是否有新的会话记录生成
- 记录的
userId是否与登录用户ID匹配 expires字段是否为未来有效时间
如果没有会话记录,说明Auth.js在authorize返回用户后未触发自动会话创建,需要检查:
- Prisma Schema是否包含Auth.js要求的完整模型(User、Session、Account、VerificationToken)
- 用户对象是否包含Auth.js必需的字段(
id、email等,确保Prisma的User模型主键为id且字段类型符合要求)
3. 检查Session回调的正确性
你的session回调中添加了session.user.role = user.role,这里要确保:
- Prisma的User模型确实存在
role字段 - 回调正确返回修改后的session对象(当前代码逻辑正确,但可临时注释这部分,测试是否是回调导致的会话异常)
4. 确认signIn调用的参数
如果是客户端组件中调用signIn,确保参数传递正确:
// 客户端组件示例 const handleLogin = async () => { const result = await signIn('credentials', { email: 'user@example.com', password: 'your-password', redirect: false, // 如需在客户端处理登录结果,设为false }) console.log(result) // 查看登录结果是否有异常 }
若redirect设为true,需确保跳转后的页面能正确读取会话,且Cookie在跳转过程中正常携带。
5. 检查Cookie配置
确保Auth.js的Cookie设置未被自定义破坏,默认配置即可。本地开发时若使用自定义域名,需保证trustHost: true(你的代码已设置),否则Cookie可能无法正确写入浏览器。
验证流程
- 移除手动生成会话的代码后重启项目
- 使用Credentials Provider完成登录
- 打开浏览器开发者工具,检查
Application -> Cookies下是否存在next-auth.session-token或__Secure-next-auth.session-token - 在page.tsx中调用
const session = await auth(),打印日志确认会话是否正常返回
内容的提问来源于stack exchange,提问作者Amith A G
相关产品推荐
相关产品推荐

