对于使用csurf保护csrf(使用cookie选项)的登录表单,我正在尝试使用jest(测试环境:节点)通过集成测试。
我已经从登录表单和set-cookie标头中提取了csrfToken,但测试仍然失败,并显示403-无效的csrf令牌。
我看不出问题是什么,希望能朝正确的方向前进。
测试文件:
'{{ password }}'
const request = require('supertest');
const {User} = require('../../server/models/user');
const cheerio = require('cheerio');
const app = require('../../app');
let user, csrfToken, password, cookies;
beforeEach( async () => {
user = await new User({
firstName: "Name",
lastName: "Surname",
email: "email@example.com",
password: "password",
isAdmin : true
}).save();
});
afterEach( async () => {
await User.deleteMany();
});
describe('/login', () => {
describe('GET /', () => {
const exec = async () => {
const res = await request(app).get(`/login`);
let $ = cheerio.load(res.text);
csrfToken = $('[name=_csrf]').val();
return res;
};
it('should return the login form', async () => {
const res = await exec();
expect(res.status).toBe(200);
expect(res.text).toMatch(/Sign In/);
});
});
describe('POST /', () => {
const getLoginCsrfs = async () => {
const res = await request(app).get(`/login`);
let $ = cheerio.load(res.text);
csrfToken = $('[name=_csrf]').val();
cookies = res.headers['set-cookie'];
return res;
};
const postLogin = async () => {
return request(app).post(`/login`)
.set('Cookie', cookies)
.send({ email: user.email,
password: password,
_csrf: csrfToken
});
};
it('should return 401 without incorrect user info', async () => {
await getLoginCsrfs();
password = 'wrongpassword';
const res = await postLogin();
expect(res.status).toBe(401)
});
it('should return 403 without csrf token/header credentials', async () => {
await getLoginCsrfs();
csrfToken = '';
cookies = '';
password = 'password';
const res = await postLogin();
expect(res.status).toBe(403)
});
it('should return 200 with correct credentials', async () => {
await getLoginCsrfs();
password = 'password';
const res = await postLogin();
expect(res.status).toBe(200)
});
});
});
答案 0 :(得分:0)
起初,我认为问题与set-cookie中的_csrf有关,但是在重新检查解决方案后很简单,
const postLogin = async () => {
return request(app).post(`/login`)
.type('form')
.set('Cookie', cookies)
.send({ email: user.email,
password: password,
_csrf: csrfToken
});
};
我没有看到.type('form'),它与表单中的csrfToken有关(所有表单数据)都没有显示。
PASS tests/integration/login.test.js (5.661s)
/login
GET /
✓ should return the login form (489ms)
POST /
✓ should return 401 without incorrect user info (443ms)
✓ should return 403 without csrf token/header credentials (131ms)
✓ should return 200 with correct credentials (255ms)
我一直在四处搜寻,并考虑了与开玩笑/超级测试和多个cookie有关的问题,但与以往一样,该解决方案更加简单明了,更贴近家庭。