将路由拆分为不同的文件/模块时,获取“ForbiddenError:invalid csrf token”

时间:2016-05-19 19:06:09

标签: node.js express csrf

我在csurf项目中使用express。我有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标记。

有什么想法吗?

1 个答案:

答案 0 :(得分: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);