html - /favicon.ico 在 Node JS 中登录后
问题描述
我login/register
在我的网站上使用 express(护照)创建了一个系统,并且在用户被重定向到登录页面之前保存了 originalUrl,但每次登录后,用户都被重定向到/favicon.ico
而不是保存的 Url。有人可以告诉我问题的原因是什么吗?
我的 app.use():
app.use((req, res, next) => {
if (!['/login'].includes(req.originalUrl)) {
req.session.returnTo = req.originalUrl;
}
res.locals.currentUser = req.user;
res.locals.success = req.flash('success');
res.locals.error = req.flash('error');
next();
})
我的 /login 获取和发布请求:
app.get('/login', (req, res) => {
res.render('login');
})
app.post('/login', passport.authenticate('local', { failureFlash: true, failureRedirect: '/login' }), (req, res) => {
const redirectUrl = req.session.returnTo || '/';
console.log(redirectUrl);
delete req.session.returnTo;
res.redirect(redirectUrl);
})
解决方案
您的会话中有两个传入请求之间的竞争条件。
您的app.use()
中间件将看到/favicon.ico
请求并将覆盖req.session.returnTo
您的login
路由可能刚刚设置的值。如果这两个请求一个接一个地出现(这可能是在浏览器第一次访问您的站点时),那么该/favicon.ico
路由将弄乱您刚刚尝试使用该/login
路由设置的会话状态。
我不知道该中间件试图做什么,但看起来它非常有能力覆盖会话中其他请求正在使用的内容。通过将最终的重定向 URL 放在查询参数中,登录后的重定向要安全得多。然后它在服务器上是无状态的,并且当有多个来自同一用户的服务器传入请求时,它不受这些类型的竞争条件的影响。
仅供参考,您还可以通过将此路由处理程序放在中间件之前相当容易地防止此特定问题(尽管不是其他潜在的竞争条件):
// put this before your middleware
app.get("/favicon.ico", (req, res) => {
res.sendStatus(404);
// or instead of a 404, send an actual favicon.ico file
// just don't let routing continue to your middleware
});
这将使您的中间件在/favicon.ico
被请求时根本无法运行,从而防止在特定位置导致与您的会话数据发生竞争条件。
推荐阅读
- python - How do I import a module created with pybind11 on Ubuntu
- python - 等待后无法杀死子进程
- python - XgBoost 精度结果在每次运行时都不同,但参数相同。我怎样才能使它们保持不变?
- node.js - 为数组中的每个元素添加唯一值
- jquery - 在页面加载后使用 jQuery 加载 CSS 来完成
- java - HAPI HL7 验证引发异常
- spotfire - 基于 Spotfire 中的日期序列排名
- haskell - Haskell QuasiQuotes Text.RawString.QQ 插值
- vbscript - 在 HTA 中使用状态更新文本区域
- javascript - 使用 React、Jest、React-Testing-Library 测试失败案例