登录后未跳转至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有效期等配置可按需添加 }));
验证步骤
- 访问需要登录的
campgrounds/edit页面,会自动重定向到/login。 - 查看服务器控制台,确认
req.session.returnTo的值为目标编辑页面路径。 - 提交登录表单,检查页面是否正确跳转到预设的编辑页面。
内容的提问来源于stack exchange,提问作者ash54321
相关产品推荐
相关产品推荐

