Passport.js与Prisma集成问题:认证及序列化代码报错求助
Passport.js + Prisma + Postgres 适配问题解决方案
1. 修复 LocalStrategy 认证逻辑
你的认证代码崩溃的核心问题是Prisma的查询方法不支持回调参数——它返回Promise,不能照搬Mongoose的回调写法。另外直接明文对比密码是严重安全漏洞,必须用哈希验证。
修正后的代码:
const bcrypt = require('bcrypt'); // 先安装依赖:npm i bcrypt passport.use(new LocalStrategy(async (username, password, done) => { try { // 用findUnique替代findFirst(建议给User.username添加@unique约束) const user = await prisma.user.findUnique({ where: { username } }); if (!user) return done(null, false, { message: 'Incorrect username' }); // 验证哈希密码,禁止直接对比明文 const passwordMatch = await bcrypt.compare(password, user.password); if (!passwordMatch) return done(null, false, { message: 'Incorrect password' }); return done(null, user); } catch (err) { return done(err); } }));
提醒:在Prisma Schema中给
User.username添加@unique约束,确保查询的唯一性与性能。
2. 完善 deserializeUser 实现
你的代码遗漏了done回调调用,导致Passport无法完成反序列化流程。同时用findUnique(id是主键,必然唯一)替代findFirst:
passport.deserializeUser(async (id, done) => { try { const user = await prisma.user.findUnique({ where: { id } }); done(null, user); // 必须调用done传递用户对象给Passport } catch (err) { done(err); } });
3. serializeUser 代码验证
你的serializeUser实现是完全正确的,这是Passport存储用户session的标准写法:
passport.serializeUser((user, done) => { done(null, user.id); });
额外生产环境注意事项
- 注册用户时必须先哈希密码再存入数据库:
const hashedPwd = await bcrypt.hash(userInputPassword, 10); await prisma.user.create({ data: { username, password: hashedPwd } }); - 确保Prisma Schema中
User.id的类型与Postgres数据库一致(常用String/Int,UUID需显式声明)
内容的提问来源于stack exchange,提问作者kevin
相关产品推荐
相关产品推荐

