【问题标题】:Getting "ForbiddenError: invalid csrf token" when splitting routes into different files/modules将路由拆分为不同的文件/模块时出现“ForbiddenError: invalid csrf token”
【发布时间】:2016-09-16 20:30:32
【问题描述】:

我在我的express 项目中使用csurf。我有 3 个文件:

  • app.js - 主入口点
  • routes/index.js - 索引路由
  • routes/users.js - 用户路线

这是使用 express application generator 时的标准样板。

我在 index.js 中有一条路线:

router.get('/', csrfProtection, function(req, res, next) {
  res.render('index', {
      csrfToken: req.csrfToken()
  });
});

此路由的页面包含一个表单,该表单具有一个带有 csrf 令牌的隐藏字段:

input(name='_csrf', type='hidden', value='#{csrfToken}')

一切正常,我可以在源代码中看到 csrf 令牌。

当表单被提交时,它被处理在 routes/users.js 中购买路由:

router.post('/login', csrfProtection, function(req, resp) {
    if(!validator.isAlphanumeric(req.username))
        console.log('Not alphanumeric');

    ...
});

看来问题与必须创建csrfcsrfToken 的新实例的两个文件有关。在两个路由文件的开头,我都需要它们:

var csrf = require('csurf');
var csrfProtection = csrf({ cookie: true });

如果我将登录路由放入 routes/index.js 中,它可以正常工作,这让我觉得可能两个实例都使用了不同的 csrf 令牌。

有什么想法吗?

【问题讨论】:

  • 一个常见的错误是在 body-parser 中间件之前添加 csurf 中间件。此外,必须首先初始化会话中间件或 cookie 解析器。

标签: node.js express csrf


【解决方案1】:

是的,我相信它使用了不同的 CSRF 令牌。我通过在我的子模块中定义一个 init 函数,然后将 CSRF 令牌传递给它来解决这个问题。这样 CSRF 令牌只会被创建一次。我认为在 app.js 中创建 CSRF 令牌可能是最好的,然后您可以将其传递到您的各个子模块中。

例如:

在 users.js 中:

function init(router, csrfProtection) {
    router.post('/login', csrfProtection, function(req, resp) {
        if(!validator.isAlphanumeric(req.username))
            console.log('Not alphanumeric');
        ...
    });
}

module.exports.init = init;

在 app.js 中:

...initialize router and CSRF protection...

var users = require('./users.js');
users.init(router, csrfProtection);

【讨论】:

    猜你喜欢
    • 2021-04-28
    • 2017-05-21
    • 2023-03-22
    • 2016-05-05
    • 2017-07-10
    • 2018-03-05
    • 2018-06-24
    • 2011-11-10
    • 1970-01-01
    相关资源
    最近更新 更多