I'm trying to write a test for my server side form validation but I keep getting a Forbidden error. It seems that this needs to be a 2 step process. Step 1, acquire the CSRF value from the form. Step 2, use the CSRF value to post to the form handler. However no matter how I try to post I get a forbidden error.
--full test: .js#L57-L100
I've tried changing the following line thusly: .js#L85
.send({name: 'foo', 'X-CSRF-Token': token})
.set('X-CSRF-Token', token)
.set('Cookie', ['X-CSRF-Token=' + token])
But nothing I try will seem to satisfy the CSRF requirement. The more I try the more plex this gets for what seems like a simple thing. Maybe I'm going about this all wrong. Any ideas?
I'm trying to write a test for my server side form validation but I keep getting a Forbidden error. It seems that this needs to be a 2 step process. Step 1, acquire the CSRF value from the form. Step 2, use the CSRF value to post to the form handler. However no matter how I try to post I get a forbidden error.
--full test: https://github./socketwiz/swblog/blob/master/test/contact.js#L57-L100
I've tried changing the following line thusly: https://github./socketwiz/swblog/blob/master/test/contact.js#L85
.send({name: 'foo', 'X-CSRF-Token': token})
.set('X-CSRF-Token', token)
.set('Cookie', ['X-CSRF-Token=' + token])
But nothing I try will seem to satisfy the CSRF requirement. The more I try the more plex this gets for what seems like a simple thing. Maybe I'm going about this all wrong. Any ideas?
Share Improve this question asked Apr 17, 2014 at 2:43 Ricky NelsonRicky Nelson 87610 silver badges24 bronze badges 3- Does this clear anything up? jb.demonte.fr/blog/expressjs-angularjs-csrf – adrichman Commented Apr 17, 2014 at 2:46
- @adrichman, I guess I should have said that it works just fine from my form, I just can't figure out how to write a test for it. When the test tries to post it gets a Forbidden error no matter what I try :( – Ricky Nelson Commented Apr 17, 2014 at 2:52
- I'm not certain about the syntax you are referencing, but it looks like you may need to refactor so that you are specifically setting an 'x-csrf-token' HEADER equal to the token located on the cookie. – adrichman Commented Apr 17, 2014 at 3:00
2 Answers
Reset to default 17Thanks @shawnzhu, you ment on cookies helped me figure out what I needed to do. I had an idea that I was over plicating it. Here is what I came up with:
https://github./socketwiz/swblog/blob/master/test/contact.js
it('should not post just a name', function(done) {
request(mock)
.get('/contact')
.end(function(err, res){
var $html = jQuery(res.text);
var csrf = $html.find('input[name=_csrf]').val();
request(mock)
.post('/api/contact.json')
.set('cookie', res.headers['set-cookie'])
.send({
_csrf: csrf,
name: 'Mary Jane'
})
.expect(function(res){
assert.equal(undefined, res.body.name);
assert.equal('You must provide a valid email address', res.body.email);
assert.equal('You must provide a message', res.body.message);
})
.expect(500, done);
});
});
The express csrf middleware saves a secret in session to validate csrf token, while I guess you use cookieSession middleware as session store. So you need to resend the session cookies when POST the data with csrf token, the express can use the secret in session to validate your csrf token.