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

登录后未跳转至req.session.returnTo路径,始终重定向至/campgrounds问题

问题解决方法

核心原因

Passport的authenticate中间件在认证成功时,默认会调用req.logIn重新生成session(防范会话固定攻击),这会导致原session中存储的returnTo属性被清空,因此后续无法读取到预设的跳转地址。

解决方案

1. 确保returnTo的存储时机正确

要保证returnTo是在用户被重定向到登录页之前就存入session的,通常在登录验证中间件中处理:

// 登录验证中间件
function isLoggedIn(req, res, next) {
  if (!req.isAuthenticated()) {
    // 存储当前请求的原始地址
    req.session.returnTo = req.originalUrl;
    req.flash('error', '请先登录');
    return res.redirect('/login');
  }
  next();
}

// 在需要登录的路由上挂载该中间件
router.get('/campgrounds/:id/edit', isLoggedIn, (req, res) => {
  // 编辑页面的业务逻辑
});

2. 在登录认证前提前保存returnTo

修改POST登录路由,在Passport认证流程启动前,先把returnTo从session中取出保存,避免被session重置操作清空:

router.post('/login', (req, res, next) => {
  // 提前取出并保存跳转地址
  const redirectUrl = req.session.returnTo || '/campgrounds';
  // 清除session中的returnTo,避免后续登录重复使用
  delete req.session.returnTo;

  passport.authenticate('local', { failureFlash: true, failureRedirect: '/login' }, (err, user) => {
    if (err) return next(err);
    if (!user) {
      // 登录失败时,把跳转地址重新存回session
      if (redirectUrl !== '/campgrounds') {
        req.session.returnTo = redirectUrl;
      }
      return res.redirect('/login');
    }
    req.logIn(user, (err) => {
      if (err) return next(err);
      req.flash('success', 'Welcome back!');
      res.redirect(redirectUrl);
    });
  })(req, res, next);
});

3. 检查session基础配置

确认你的express-session中间件配置没有自动清空session的设置,示例配置如下:

app.use(session({
  secret: 'your-custom-secret-key',
  resave: false,
  saveUninitialized: false,
  // 其他如cookie有效期等配置可按需添加
}));

验证步骤

  1. 访问需要登录的campgrounds/edit页面,会自动重定向到/login。
  2. 查看服务器控制台,确认req.session.returnTo的值为目标编辑页面路径。
  3. 提交登录表单,检查页面是否正确跳转到预设的编辑页面。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.24 20:09:21