我在express项目中使用csurf。我有3个文件:
- app.js-主要入口点
- 路由/index.js-索引路由
- routes/users.js-用户路由
当使用express应用程序生成器时,它是标准样板。
我在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');
...
});
问题似乎与两个文件都必须创建csrf
和csrfToken
的新实例有关。在两个路由文件的开头,我需要它们,如下所示:
var csrf = require('csurf');
var csrfProtection = csrf({ cookie: true });
如果我将登录路由放入routes/index.js中,它可以正常工作,这让我认为这两个实例可能都使用了不同的csrf令牌。
有什么想法吗?
是的,我相信它使用了不同的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);