I have this odd behavior I get an error just the first time my page loads, basically is 'EBADCSRFTOKEN' I've been trying to figure it out why it happens only the first time the page loads, if I hit refresh and get a new token everything works fine.
the same scenario happens when I delete the csurf cookie, hit refresh and I get a new token, but the first time always fail I'm not sure why both the expected string and the token don't match.
a snippet of the code (I'm using MEANJS stack):
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();
});
};
Different values for the token:
Cookie
fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA
req.csrfToken() (in middleware request)
fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA
Expected (in csurf library)
fgeHcu6v-T9CuTWL8hVGHMtSskeh0yzqaP0k
Token (in csurf library)
fgeHcu6v-hgdCMuRjnmE9BYV_QrvrfzwJoeA
seems like the expected is similar to the token and they differ just after the dash, any ideas?
UPDATE:
Basically, I followed @shakiba recommendation I removed my custom middleware and I let the csurf library handle it.
I changed the configuration to:
app.use(csrf({ cookie: true }));
now I get a cookie named _csrf, now the issue is a little bit different, the token value is the same as the secret token in the library, so when the library "converts" the secret token to be the expected token they don't match.
These are some example values:
Cookie BDir8-6hkdy-_YsXNb305IIx
Secret BDir8-6hkdy-_YsXNb305IIx
Token BDir8-6hkdy-_YsXNb305IIx
Expected BDir8-zbwt4-K_Uv8t1TtmxxctkfcMN1M