我有一个奇怪的行为,当我的页面加载时,我只会得到一个错误,基本上是'EBADCSRFTOKEN'。我一直在尝试找出它为什么只在第一次加载页面时发生,如果我点击刷新并获取一个新的令牌,一切都正常。
当我删除csurf cookie,点击刷新并获取一个新的令牌时,同样的情况也会发生,但第一次总是失败,我不确定为什么期望的字符串和令牌都不匹配。
以下是代码片段(我正在使用MEANJS堆栈):
当我删除csurf cookie,点击刷新并获取一个新的令牌时,同样的情况也会发生,但第一次总是失败,我不确定为什么期望的字符串和令牌都不匹配。
以下是代码片段(我正在使用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
});
});
Middleware:
module.exports = function(app) {
app.use(function(req, res, next){
res.cookie('x-xsrf-token', req.csrfToken());
res.locals.csrftoken = req.csrfToken();
next();
});
};
令牌的不同值:
Cookie
fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA
req.csrfToken()(在中间件请求中)
fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA
期望值(在csurf库中)
fgeHcu6v-T9CuTWL8hVGHMtSskeh0yzqaP0k
令牌(在csurf库中)
fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA
看起来期望值与令牌相似,只是在破折号后略有不同,有什么想法吗?
更新:
基本上,我按照@shakiba的建议去掉了自定义中间件,让csurf库处理它。
我改变了配置为:
app.use(csrf({ cookie: true }));
现在我得到了一个名为_csrf的cookie,现在问题有点不同,令牌值与库中的秘密令牌相同,因此当库"转换"秘密令牌成为预期的令牌时它们不匹配。
以下是一些示例值:
Cookie BDir8-6hkdy-_YsXNb305IIx
Secret BDir8-6hkdy-_YsXNb305IIx
Token BDir8-6hkdy-_YsXNb305IIx
Expected BDir8-zbwt4-K_Uv8t1TtmxxctkfcMN1M
req.csrfToken()
将其分配给视图本地变量,可以像你在中间件中所做的那样将其分配给res.locals
,或者在res.render(view, locals)
中。目前你正在使用 cookie/secret 值作为令牌。 - Ali Shakiba