POST request JSON must be added to req after the attachment of cookies--why?
See original GitHub issueThe following test passes:
var request = require('supertest');
var superagent = require('superagent');
describe('Example:', function() {
var agent;
beforeEach(function(done) {
agent = superagent.agent();
var req = request('http://example.com').get('/getsomecookies');
req.end(function(err, result) {
if (!err) {
agent.saveCookies(result.res);
done();
} else {
done(err);
}
});
});
it('should successfully post some JSON', function(done) {
var req = request('http://example.com').post('/postsomejson')
agent.attachCookies(req);
req.send({my: 'JSON'});
var csrfToken = (/XSRF-TOKEN=(.*?);/.exec(req.cookies)[1]);
req.set('X-XSRF-TOKEN', unescape(csrfToken));
req.end(function(err, result){
expect(res.status).to.eql(200);
done();
});
});
});
However, simply swapping the attachment of cookies with the setting of the JSON causes the test to fail–the server responds with 403. That is, the following fails:
it('should successfully post some JSON', function(done) {
var req = request('http://example.com').post('/postsomejson').send({my: 'JSON'});
agent.attachCookies(req);
...
});
When I look on the server (express proxied by nginx, using the express.csrf middleware) to see what is going on, in the unsuccessful case the secret loaded from req.session.csrfSecret, which is used to match the X-XSRF-TOKEN header, is undefined. In the successful case, the secret loaded from req.session.csrfSecret is exactly what it should be, namely the secret created by the GET request to /getsomecookies.
Interestingly, if I make the POST request without trying to send any JSON, I at least don’t get a 403 response (though the test would fail with a 400 because I didn’t provide any JSON for the server to do something with). That is, this works too:
it('should successfully post some JSON', function(done) {
var req = request('http://example.com').post('/postsomejson');
agent.attachCookies(req);
...
});
So, what is it about attachCookies that is interfering with the setting of the JSON sent in the request? Clearly the server is seeing something different in each case. Is this problem documented anywhere?
Issue Analytics
- State:
- Created 9 years ago
- Comments:7
Top GitHub Comments
Also, this means that
agent.get(url).end(cb)
doesn’t get its cookies set whileagent.get(url,cb)
does, which is completely bonkers. I’m assuming this is a regression?Where is any of this saveCookies/attachCookies stuff documented? I don’t see any of it in https://github.com/visionmedia/superagent/blob/master/test/node/agency.js
Furthermore, depending on its behavior to be used externally at all is a defect, since these functions are specifically marked “private” in the comments preceding their definition.