PassportJS配合Express、Axios使用时req.user返回undefined问题求助
问题原因及修复方案
1. deserializeUser未处理异步逻辑
你封装的getUserById方法返回的是Promise对象,当前deserializeUser直接将Promise传入done回调,Passport无法拿到实际的用户数据,导致req.user挂载失败。
修改passport-config.ts中的反序列化逻辑:
passport.deserializeUser(async (id, done) => { try { const user = await getUserById(id); return done(null, user); } catch (error) { return done(error, null); } });
2. 中间件加载顺序错误
你当前的代码执行顺序是先定义路由,再初始化Passport配置,导致路由绑定时Passport的序列化、反序列化逻辑还未注册,无法正确解析session中的用户信息。
调整index.ts的中间件加载顺序为:
// 第一步:加载基础解析中间件 app.use(express.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(cookieParser(process.env.SESSION_SECRET)); // 跨域配置(如果前端端口和后端3000不一致需要添加) // const cors = require('cors'); // app.use(cors({ origin: 'http://localhost:<前端运行端口>', credentials: true })); // 第二步:加载session相关中间件 app.use(flash()); app.use(session({ key: "userId", secret: process.env.SESSION_SECRET, resave: false, saveUninitialized: false, cookie: { maxAge: 86400000, // 替换原有错误的expires配置,maxAge直接传毫秒数表示有效期 httpOnly: true } })); // 第三步:先完成Passport配置初始化,再启用Passport中间件 const initializePassport = require('./passport-config'); initializePassport( passport, (username: string) => { // 原有查询逻辑保持不变 }, (id: number) => { // 原有查询逻辑保持不变 } ); app.use(passport.initialize()); app.use(passport.session()); // 第四步:最后定义路由、挂载路由 router.get('/login', (request, response) => { // 原有校验逻辑保持不变 }); // 前后端分离场景不建议用redirect配置,修改登录接口直接返回JSON router.post('/login', passport.authenticate('local', { failureFlash : true }), (req, res) => { res.send({ loggedIn: true, user: req.user }); }); app.use('/api/v1', router);
额外说明
你看到的cookie格式是正常的,express-session会将session内容加密后存在客户端cookie,不会明文存储用户对象,服务端会通过配置的SESSION_SECRET解密拿到session中的用户ID,再通过deserializeUser查询完整用户信息挂载到req.user上。
内容的提问来源于stack exchange,提问作者whalebeach
相关产品推荐
相关产品推荐

