我正在使用nodejs,express开发一个简单的Web应用程序,当我切换到session和csrf时,我的PUT,DELETE和POST请求都失败了。 有错误:
error: Forbidden at Object.exports.error (appFolder/node_modules/express/node_modules/connect/lib/utils.js:63:13) at createToken (appFolder/node_modules/express/node_modules/connect/lib/middleware/csrf.js:82:55)
我查看了这一行,发现它调用checkToken
function
调用defaultValue,它在请求中找到csrf标记,如下所示:
function defaultValue(req) {
return (req.body && req.body._csrf)
|| (req.query && req.query._csrf)
|| (req.headers['x-csrf-token'])
|| (req.headers['x-xsrf-token']);
}
这给出了null或undefined值,而我的checkToken失败了。
我的PUT请求是由骨干生成的,我只是发送模型的数据。所以我开始在cookie中发回令牌。 我在cookie中设置令牌,如:
app.use(express.cookieParser());
app.use(express.session({
secret: '6767678376-3hudh-2u78di90-kjdu39i-jfujd'
}));
app.use(function(req,res,next) {
console.log("Body " + JSON.stringify(req.headers));
return next();
});
app.use(express.csrf());
app.use(express.static(path.join(__dirname, 'public')));
app.use(function(req, res, next) {
console.log(req.body);
res.cookie('x-csrf-token', req.csrfToken());
console.log('CSRF : ' + req.csrfToken());
//res.session._csrf = req.csrfToken();
return next();
});
并将defaultValue(req)
更改为
function defaultValue(req) {
var csrf_token = (req.body && req.body._csrf)
|| (req.query && req.query._csrf)
|| (req.headers['x-csrf-token'])
|| (req.headers['x-xsrf-token']);
if(csrf_token)
return csrf_token;
// find in cookie.
if(!req.headers['cookie'])
return undefined;
var csrfTokenInCookie = (req.headers['cookie'].split('x-csrf-token='));
if(csrfTokenInCookie && (csrfTokenInCookie.length == 2)) {
return csrfTokenInCookie[1];
}
var xsrfTokenInCookie = (req.headers['cookie'].split('x-xsrf-token='));
if(xsrfTokenInCookie && (xsrfTokenInCookie.length == 2)) {
return xsrfTokenInCookie[1];
}
}
现在defaultValue正确地给出了csrftoken标记,但checkToken
再次失败。
该文件位于:csrf.js
我做错了什么?
或者它怎么能不生成正确的令牌呢?
答案 0 :(得分:1)
您的问题是Express不会在POST / PUT / DELETE请求的标头中发回CSRF令牌。当标题丢失时,Express的CSRF中间件正在拒绝这些请求。
以下是有关在Backbone中添加所需标头的信息:How to protect against CSRF when using Backbone.js to post data?
答案 1 :(得分:0)
您尝试验证Cookie并表达会话这些将是不同的令牌,因此它将失败您必须选择cookie或令牌。
作者在这里提到它 https://github.com/expressjs/csurf/issues/52
我个人建议完全禁用cookie并通过标题和表单体传递令牌 - 这对我有用。