使用passport-discord做登录认证,页面刷新后用户认证状态失效如何解决
问题修复方案
1. 修复serializeUser和deserializeUser逻辑
你当前直接序列化完整用户对象进session,建议改为只序列化用户id,反序列化时从你的profiles.json中读取用户数据,避免session存储过大或者数据不一致问题:
passport.serializeUser((user, done) => { // 只存用户id到session done(null, user.id); }); passport.deserializeUser((id, done) => { // 从profiles中读取完整用户数据 const user = profiles[id]; done(null, user || null); });
2. 修正session配置
express-session默认配置的resave: true和saveUninitialized: true会导致很多异常的session状态问题,按照官方推荐修改为以下配置:
app.use(session({ secret: 'secrettexthere', // 生产环境请替换为更复杂的密钥 saveUninitialized: false, resave: false, cookie: { maxAge: 60000 * 60 * 24, // 如果你用的是https协议,加上secure: true // secure: process.env.NODE_ENV === 'production' } }))
3. 补全Discord授权回调路由
你目前只贴了发起授权的/auth路由,必须补充回调路由处理授权成功的逻辑,否则passport不会自动写入登录态:
app.get("/auth/callback", passport.authenticate('discord', { failureRedirect: '/login' }), (req, res) => { // 授权成功后跳转首页 res.redirect('/'); } );
注意这个回调地址要和你Discord开发者后台设置的回调地址、以及process.env.CLIENT_REDIRECT的值完全一致。
4. 修复JSON文件异步写入的时序问题
你当前用的fs.writeFile是异步方法,还没等文件写入完成就调用了done(),极端情况下会出现数据还没写入就完成认证,后续反序列化读不到数据的问题,把done()放到写入回调里即可:
fs.writeFile("./profiles.json", JSON.stringify(profiles, null, 4), err => { if(err) throw err; let finduser = profiles[profile.id]; console.log(finduser); done(null, finduser); })
5. 注意express-session存储限制
默认express-session用内存存储session,只适合开发测试用,如果你服务重启、或者并发请求多的时候也会出现session丢失的问题,稳定使用建议换成express-session支持的持久化存储即可。
内容的提问来源于stack exchange,提问作者nahtap
相关产品推荐
相关产品推荐

