質問

I am developing a simple web app using nodejs, express and when i switched to session and csrf, my PUT, DELETE and POST Requests are failing. with error:

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)

I looked at this line, and found that it calls checkToken function which calls the defaultValue which finds the csrf token in the request like this:

function defaultValue(req) {
  return (req.body && req.body._csrf)
    || (req.query && req.query._csrf)
    || (req.headers['x-csrf-token'])
    || (req.headers['x-xsrf-token']);

}

This was giving null or undefined value, and my checkToken was failing.

My PUT requests are generated by backbone and i just send the model's data. so i started sending back the token in cookie. I set the token in cookie like:

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();
});

and changed the defaultValue(req) to

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];
  }
}

Now defaultValue is giving the csrftoken token rightly, but again checkToken is failing.

The file is here: csrf.js

What am i doing wrong ?

Or how can it not generate back the right-token ?

役に立ちましたか?

解決

Your issue is with Express not sending the CSRF token back in a header for POST/PUT/DELETE requests. Express's CSRF middleware is doing the correct thing in rejecting these requests when the header is missing.

Here's info on adding the header you need in Backbone: How to protect against CSRF when using Backbone.js to post data?

他のヒント

your trying to validate the cookie and express session these will be different tokens so it will fail you would have to choose one either the cookie or token.

the author mentions it here https://github.com/expressjs/csurf/issues/52

personally i would recommend disabling cookies altogether and pass the token through the headers and form body -- this worked for me.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top