在将路由拆分成不同的文件/模块时,得到“ForbiddenError:无效的csrf令牌”

我在快速项目中使用csurf 。 我有3个文件:

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

它是使用快速应用程序生成器时的标准样板。

我在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'); ... }); 

看起来问题是两个文件必须创build新的csrf实例和csrfToken 。 在这两个path文件的头部,我需要他们这样的:

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

如果我把login路由到routes / index.js,它工作正常,这让我想也许这两个实例使用不同的csrf标记。

有任何想法吗?

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

例如:

在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);