You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Passport库deserializeUser函数未执行的问题求助

前后端分离应用Passport登录后会话失效问题

我正在开发一个前后端分离应用,前端运行在localhost:3000,后端运行在localhost:4000。使用Passport库登录时,已成功通过数据库校验邮箱和密码,且serializeUser函数的日志正常输出。但登录成功后从/login页面跳转至首页,调用后端/plans GET接口时,deserializeUser函数未执行,控制台无对应日志输出,且req.isAuthenticated()返回false。已知Passport会通过会话保存信息,每次请求都会执行deserializeUser以维持登录状态,但不清楚问题所在。

相关代码

Passport核心逻辑代码

passport.serializeUser((user, done) => {
    console.log(`serialize user: ${JSON.stringify(user)}`)
    done(null, user._id)
})

passport.deserializeUser((id, done) => {
    // 期望在服务器控制台看到这些日志
    console.log(`descrialize user:::::::`)
    console.log(id)
    User.findById(id).then((user) => done(null, user))
})

app.post('/login', (req, res, next) => {
    passport.authenticate(
        'local',
        (err, user, info) => {
             if (err) return next(err)
             if (user) {
             req.logIn(user, function (err) {
                 if (err) return next(err)
                 res.cookie('connect_uid', req.user._id)
          res.status(200).json({
            auth: req.isAuthenticated(),
          })
        })
      }
      return res.json(info)
    },
  )(req, res, next)
})

app.get('/plans', (req, res) => {
  console.log('>>>>>>>>>>>>>> /plans')
  console.log(`isAuthenticated: ${req.isAuthenticated()}`)

  if (req.user) {
    res.json({ message: 'success' })
  } else {
    res.json({ message: 'not found user' })
  }
})

Express中间件配置代码

const app = express()

app.use(
  cookieSession({
    name: 'markers-cookie-session',
    keys: [process.env.COOKIE_KEY],
    maxAge: 60 * 60 * 24,
  }),
)

app.use(function (request, response, next) {
  if (request.session && !request.session.regenerate) {
    request.session.regenerate = (cb) => {
      cb()
    }
  }
  if (request.session && !request.session.save) {
    request.session.save = (cb) => {
      cb()
    }
  }
  next()
})

app.use(express.json())
app.use(express.urlencoded({ extended: true }))
app.use(cookieParser())

app.use(
  session({
    secret: process.env.COOKIE_KEY,
    resave: false,
    saveUninitialized: false,
    cookie: {
      domain: 'http://localhost:3000',
      sameSite: 'none',
      secure: false,
    },
  }),
)

app.use(
  cors({
    origin: 'http://localhost:3000',
    credentials: true,
    exposedHeaders: ['set-cookie'],
  }),
)

app.use(passport.initialize())
app.use(passport.session())
require('./config/passport')

问题排查与解决

1. 会话中间件冲突

同时启用了cookie-session和express-session两个会话管理中间件,二者机制冲突,导致Passport无法正确读取会话信息。必须移除其中一个,推荐保留express-session,它更适配复杂场景的会话需求。

2. Cookie配置错误

  • domain字段设置错误:应填写域名(如localhost)而非完整URL,前端后端同域时可留空或设为localhost;
  • sameSite与secure不匹配:sameSite: 'none'要求secure: true,但本地HTTP环境下需将sameSite改为lax或strict,否则浏览器会拒绝保存cookie;
  • maxAge单位错误:原代码值为60*60*24,单位是毫秒,实际应为60*60*24*1000才是一天有效期。

修改后的session配置示例:

app.use(
  session({
    secret: process.env.COOKIE_KEY,
    resave: false,
    saveUninitialized: false,
    cookie: {
      domain: 'localhost',
      sameSite: 'lax',
      secure: process.env.NODE_ENV === 'production', // 生产环境开启secure
      maxAge: 60 * 60 * 24 * 1000,
    },
  }),
)

3. 前端请求未携带凭证

前端调用/plans接口时,必须设置携带凭证:

  • Axios:axios.get('http://localhost:4000/plans', { withCredentials: true })
  • Fetch:fetch('http://localhost:4000/plans', { credentials: 'include' })

4. 移除多余自定义Cookie

Passport会自动通过会话管理用户标识,手动设置connect_uid cookie属于冗余操作,可能干扰会话机制,建议删除res.cookie('connect_uid', req.user._id)这一行。

内容的提问来源于stack exchange,提问作者kmyz

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 01:14:58