Fastify-passport中req.user为null,serializer与deserializer未被调用
问题根因
- 登录接口自定义认证回调未手动触发登录流程:当你给
fastifyPassport.authenticate传入自定义回调时,passport不会自动执行用户登录、序列化逻辑,必须手动调用req.logIn(user)才能触发序列化、将用户信息写入会话。 - 受保护路由未加认证校验:
/logout等需要获取用户信息的路由没有添加fastifyPassport.authenticate前置校验,fastify-passport不会自动触发用户反序列化逻辑,自然拿不到req.user。 - fastify-secure-session 配置缺失:缺少cookie相关配置,可能导致浏览器不存储会话cookie,出现会话丢失的现象。
- 业务路由写法不符合规范:将业务逻辑写在
authenticate回调中的用法不符合fastify-passport设计,会跳过正常的会话校验流程。
修复方案
1. 修正登录接口逻辑
替换原有的POST /login路由代码,手动调用req.logIn触发序列化:
fastify.post( "/login", async (req, reply) => { return fastifyPassport.authenticate('login', async (err, user, info) => { if (err) { console.warn("登录错误:", err) return reply.status(500).send({msg: "服务端错误"}) } if (!user) { return reply.status(401).send({msg: "账号或密码错误"}) } // 手动调用logIn,触发用户序列化、写入会话 await req.logIn(user) return reply.send({redirect: "/"}) })(req, reply) } )
2. 补全fastify-secure-session配置
fastify.register(fastifySecureSession, { key: fs.readFileSync(path.join(__dirname, 'secret-key')), cookie: { path: '/', httpOnly: true, // 生产环境开启secure,开发环境关闭 secure: process.env.NODE_ENV === 'production', sameSite: 'lax' } })
3. 修正路由写法,给需要用户信息的路由添加认证校验
以/logout为例,添加前置校验后反序列化逻辑会自动触发,能正常拿到req.user:
{ preValidation: fastifyPassport.authenticate("login"), handler: async (req, res) => { console.log(req.user) // 如需登出可调用logOut清空会话 await req.logOut() res.send({msg: "已登出"}) }, url: "/logout", method: "GET" }
其他业务路由(如/api/postData、/api/deleteData)同理,把业务逻辑移到handler中,仅在preValidation中保留认证逻辑即可,示例如下:
{ preValidation: fastifyPassport.authenticate("login"), handler: async (req, reply) => { const params = req.body const newData = { universidad: params.universidad, facultad: params.facultad, nombreExamen: params.nombreExamen, fechaExamen: params.fechaExamen, convocatoriaEspecial: params.convocatoriaEspecial, convocatoriaExtraordinaria: params.convocatoriaExtraordinaria, curso: params.curso } const response = await dbQuery('INSERT INTO `examenes` VALUES("' + newData.universidad + '","' + newData.facultad + '","' + newData.nombreExamen + '","' + newData.fechaExamen + '",' + newData.convocatoriaEspecial + ',' + newData.convocatoriaExtraordinaria + ',' + newData.curso + ")") return reply.send({ status: 200, newData, response }) }, url: '/api/postData', method: 'POST' }
验证逻辑
修复完成后,触发登录时序列化方法会被调用,会话cookie会正常写入浏览器,后续访问加了认证校验的路由时,反序列化方法会自动触发,req.user能正常拿到用户信息。
内容的提问来源于stack exchange,提问作者M1S0
相关产品推荐
相关产品推荐

