forwardemail / forwardemail/superagent

POST request JSON must be added to req after the attachment of cookies--why?

Open
#352 7 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.