I'm trying to write a test for a POST
route in my Express application using Mocha, Chai and ChaiHttp, but I can't get it to work due to the fact that I keep getting an HTTP 403
response whenever submitting my CSRF token. Below is the code that I have up until now:
express.js configuration file
...
app.use(session(config.SESSION));
// csrf is the 'csurf' module
app.use(csrf());
app.use((req, res, next) => {
res.cookie('XSRF-TOKEN', req.csrfToken());
return next();
});
...
User.test.js
'use strict';
process.env.NODE_ENV = 'test';
const User = require('../server/models/User');
const chai = require('chai');
const chaiHttp = require('chai-http');
const server = require('../index');
const utils = require('../utils');
chai.use(chaiHttp);
describe('Users', () => {
beforeEach((done) => {
User.remove({}, (err) => {
done();
});
});
after((done) => {
server.close();
done();
});
...
/*
* [POST] /user
*/
describe('[POST] /user', () => {
it('should return a JSON object with a "success" property equal to "true" when creating a new user', (done) => {
const userObj = utils.generateUserObject();
chai.request(server)
.get('/api')
.end((error, response) => {
userObj._csrf = utils.extractCsrfToken(response.headers['set-cookie']);
/*
* Accurately logs the _csrf property with the correct CSRF token that was retrieved via the initial GET request
*
* Example output:
*
* {
* username: 'Stacey89',
* first_name: 'Gregg',
* last_name: 'King',
* ...
* _csrf: 'vBhDfXUq-jE86hOHadDyjgpQOu-uE8FyUp_M'
* }
*
*/
console.log(userObj);
chai.request(server)
.post('/api/user')
.set('content-type', 'application/x-www-form-urlencoded')
.send(userObj)
.end((err, res) => {
res.should.have.status(200);
res.body.should.be.a('object');
res.body.should.have.property('success').eql('true');
done();
});
});
});
...
utils.js
...
extractCsrfToken(cookiesObj) {
const cookiesArray = Array.prototype.join.call(cookiesObj, '').split(';');
let csrfToken = 'NOT FOUND';
cookiesArray.forEach((cookie) => {
if (cookie.includes('XSRF-TOKEN')) {
csrfToken = cookie.split('=').splice(1, 1).join('');
}
});
return csrfToken;
}
...
When I run the above test, I get the following error:
ForbiddenError: invalid csrf token
...
POST /api/user 403
The strange thing is that if I do a POST request from Postman with the exact same configuration as the one previously described, I successfully get the response I am looking for and the form submission succeeds.
It appears to not be working only when submitting the userObj
from my test suite.
Aucun commentaire:
Enregistrer un commentaire