forwardemail / forwardemail/superagent
POST request JSON must be added to req after the attachment of cookies--why?
- Dominant language
- JavaScript
- Stars
- 16.6k
- Forks
- 1.3k
- PR merge metrics
- No merged PRs in 30d
Description
The 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?
Contributor guide
Assessment
This issue has not been assessed yet.