Csurf无效的csrf令牌Express / nodejs

我有这种奇怪的行为,我只是第一次加载我的页面时,得到一个错误,基本上是'EBADCSRFTOKEN'我一直在试图弄清楚为什么只发生在页面加载,如果我刷新,并得到一个新的令牌一切工作正常。

同样的情况发生在我删除csurf的cookie,刷新刷新,我得到一个新的令牌,但第一次总是失败我不知道为什么期待的string和令牌不匹配。

代码片段(我正在使用MEANJS堆栈):

app.use(busboy()); app.use(bodyParser.urlencoded({ extended: false })); app.use(bodyParser.json({limit: '50mb'})); app.enable('jsonp callback'); var cp = cookieParser; app.use(cp()); var mStore = new mongoStore({ db: db.connection.db, collection: config.sessionCollection }); app.use(session({ secret: config.sessionSecret, store: mStore, cookie: {httpOnly: false}, key:config.cookieKey, })); app.use(csrf()); //setting up a middleware var middlewareFiles = [ 'csrf-rule.server.js', 'secure-routes.server.js' ]; middlewareFiles.forEach(function(routeSecure){ require(path.resolve('./app/middleware/'+routeSecure))(app); }); app.use(function(err, req, res, next) { if (!err) return next(); if(err.code === 'EBADCSRFTOKEN'){ res.json(484, {data: 'invalid csrf token.'}); return; } // Error page res.status(500).render('500', { error: err.stack }); }); 

中间件:

 module.exports = function(app) { app.use(function(req, res, next){ res.cookie('x-xsrf-token', req.csrfToken()); res.locals.csrftoken = req.csrfToken(); next(); }); }; 

令牌的不同值:

曲奇饼

fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA

req.csrfToken()(在中间件请求中)

fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA

预计(在csurf库)

fgeHcu6v-T9CuTWL8hVGHMtSskeh0yzqaP0k

令牌(在csurf库中)

fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA

看起来像预期的类似的令牌,他们不同之后短跑,任何想法?

更新:

基本上,我跟着@shakibabuild议我删除了我的自定义中间件,我让csurf库处理它。

我改变了configuration:

 app.use(csrf({ cookie: true })); 

现在我得到一个名为_csrf的cookie,现在问题有点不同了,令牌值与库中的秘密令牌一样,所以当库秘密令牌“转换”预期的令牌时,他们不会比赛。

这些是一些示例值:

Cookie BDir8-6hkdy-_YsXNb305IIx

秘密 BDir8-6hkdy-_YsXNb305IIx

令牌 BDir8-6hkdy – _YsXNb305IIx

预计 BDir8-zbwt4-K_Uv8t1TtmxxctkfcMN1M

我相信你没有正确的使用csurf,csurf为你设置了cookie,你不应该自己设置,它的值和csrfToken()的值不同。 据我所知,从文档和源代码csrfToken()值是使用csurf为cookie设置的值生成的,因为它们状态为减轻BREACH攻击。

我做了一个简单的csurf版本,它只使用cookies,并没有做任何有关BREACH攻击的事情,因为BREACH攻击在我看来是一个独立的问题,应该在独立的模块/库中解决。 我会在github上分享它,所以你可以使用它,如果你喜欢。