отправка csrfToken и set-cookie еще 403 неверных токена csrf - PullRequest
0 голосов
/ 14 февраля 2019

Я пытаюсь пройти интеграционный тест, используя jest (test environment: node), для формы входа, которая использует csurf для защиты csrf (используя опцию cookie).

Я извлек csrfToken из формы входа в систему и заголовков set-cookie, но тест все равно не прошел с недопустимым токеном csrf 403.

Я не вижу, в чем проблемаи был бы признателен за руль в правильном направлении.

тестовый файл:

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)
    });
  });
});
 FAIL  tests/integration/login.test.js
  /login
    GET /
      ✓ should return the login form (300ms)
    POST /
      ✕ should return 401 without incorrect user info (150ms)
      ✓ should return 403 without csrf token/header credentials (130ms)
      ✕ should return 200 with correct credentials (131ms)

  ● /login › POST / › should return 401 without incorrect user info

    expect(received).toBe(expected) // Object.is equality

    Expected: 401
    Received: 403

      61 |       password = 'wrongpassword';
      62 |       const res = await postLogin();
    > 63 |       expect(res.status).toBe(401)
         |                          ^
      64 |     });
      65 |
      66 |     it('should return 403 without csrf token/header credentials', async () => {

      at Object.toBe (tests/integration/login.test.js:63:26)

  ● /login › POST / › should return 200 with correct credentials

    expect(received).toBe(expected) // Object.is equality

    Expected: 200
    Received: 403

      77 |       password = 'password';
      78 |       const res = await postLogin();
    > 79 |       expect(res.status).toBe(200)
         |                          ^
      80 |     });
      81 |   });
      82 | });

      at Object.toBe (tests/integration/login.test.js:79:26)

1 Ответ

0 голосов
/ 17 февраля 2019

Первоначально я думал, что проблема, связанная с _csrf в set-cookie, но после перепроверки решения была простой,

    const postLogin = async () => {
      return request(app).post(`/login`)
        .type('form')
        .set('Cookie', cookies)
        .send({ email: user.email,
                password: password,
                _csrf: csrfToken
        });
    };

я пропустил .type ('form'), 403 относился кcsrfВзято из формы (все данные формы), но меня не видно.

 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, но, как всегда, решение было гораздо более сложным.прямо и ближе к дому.

...