passport.authenticate的successReturnToOrRedirect无法回跳原路由仅重定向问题
Passport.js successReturnToOrRedirect 配置不生效问题修复
问题表现
调用passport.authenticate('local', { successReturnToOrRedirect: '/'})时,登录成功后无法跳转回用户此前访问的受保护路由,仅会重定向到配置中指定的默认路径。
现有登录路由实现代码:
const router = require('express').Router() const User = require('../models/user.model') const { body, validationResult } = require('express-validator') const passport = require('passport') router.get('/login', ensureNotAuthenticated, async(req, res, next) => { res.render('login') }) router.post('/login', ensureNotAuthenticated, passport.authenticate('local', { successReturnToOrRedirect: '/', failureRedirect: "/auth/login", failureFlash: true }))
复现场景
- 用户访问
/auth/profile这类需要登录权限的受保护路由时,会被鉴权逻辑拦截重定向到登录页面 - 用户完成账号密码登录后,没有跳转回之前尝试访问的
/auth/profile,只会跳转到successReturnToOrRedirect配置指定的/路径 - 完全相同的配置在Passport 0.4.1版本中可以正常实现登录后回跳原访问路由的效果
问题根因
Passport在0.5.0及以上版本中,移除了鉴权拦截时自动将用户原始访问路径写入req.session.returnTo的默认逻辑,而successReturnToOrRedirect配置的回跳逻辑完全依赖session中存储的returnTo字段,字段不存在时就会直接跳转到配置的默认路径。
修复步骤
- 在受保护路由的鉴权拦截中间件中,手动将用户当前的原始访问路径存入session的
returnTo字段,参考实现:
function ensureAuthenticated(req, res, next) { if (req.isAuthenticated()) { return next() } // 存储用户原访问路径,供登录成功后回跳使用 req.session.returnTo = req.originalUrl res.redirect('/auth/login') }
- 检查
ensureNotAuthenticated中间件逻辑,不要在渲染登录页、处理登录请求的流程中主动清空req.session.returnTo字段,避免回跳地址被覆盖。 - 登录成功跳转后Passport会自动清空session中存储的
returnTo字段,不需要额外手动清理,避免影响后续其他受保护路由的拦截逻辑。
内容的提问来源于stack exchange,提问作者Evans Ekene
相关产品推荐
相关产品推荐

