NodeJS топор ios запрос самоподписанного работает в браузере, но не в супер-тесте Jest - PullRequest
0 голосов
/ 14 апреля 2020

Я создаю NodeJS приложение, которое выполняет вызовы внешнего API. Внешний API использует самозаверяющий сертификат. Я попытался установить переменную среды process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0' . Это работает, чтобы игнорировать проверку сертификата при обычном использовании приложения. Однако запрос к той же конечной точке НЕ работает при вызове маршрута NodeJS с агентом Jest Supertest.

При выполнении случая Jest Supertest возникает ошибка проверки сертификата. Можно ли принимать самозаверяющие сертификаты при отправке запросов с использованием агента Supertest?

npm test

Error: Error: SSL Error: DEPTH_ZERO_SELF_SIGNED_CERT
          at Object.dispatchError (/home/node/app/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:54:19)
          at EventEmitter.<anonymous> (/home/node/app/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:675:20)
          at EventEmitter.emit (events.js:323:22)
          at Request.<anonymous> (/home/node/app/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:384:47)
          at Request.emit (events.js:311:20)
          at Request.onRequestResponse (/home/node/app/node_modules/request/request.js:948:10)
          at ClientRequest.emit (events.js:311:20)
          at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:603:27)
          at HTTPParser.parserOnHeadersComplete (_http_common.js:119:17)
          at TLSSocket.socketOnData (_http_client.js:476:22) undefined

NodeJS внутренний маршрут

Работает при доступе к маршруту через браузер, но не при запуске Jest Supertest. Внутренний маршрут / внутренний и это работает, но когда этот код впоследствии отправляет запрос на внешний API, имеющий самоподписанный сертификат, самозаверяющий сертификат вызывает сообщение об ошибке 500.

router.get('/internal', (req, res, next) => {

  // Set request values that are specific to this route
  const requestOptionsData = { method: `GET`, endpoint: `/external` };

  try {
    httpCtrl.makeRequest(requestOptionsData).then(result => {
      if (result.error) {
        return res.status(result.status).json(result.error.message || result.error);
      }
      return res.status(result.status).json(result);
    }).catch((error) => {
      console.error(error);
      return res.status(500).send(error);
    });
  } catch (e) {
    console.error(e);
    return res.status(500).send(e);
  }

});

NodeJS контроллер

Функция-обертка для выполнения топора ios запросов к внешнему API

httpCtrl.makeRequest = async (requestOptionsData) => {

  let result = {};

  // Set request options
  const requestOptions = httpCtrl.setApiRequestOptions(requestOptionsData);

  let response;
  try {
    response = await axios(requestOptions);
  } catch(e) {
    result.error = e.toJSON() || e;
    console.error(result.error);
    result.status = 500;
    return result;
  }

  result.status = response && response.status || 500;
  result.data = response && response.data || {};

  return result;
}

JEST Supertest

Тест, который вызывает ошибку сертификата

const app = require('../app.js');
const supertest = require('supertest');

describe('API routes', () => {

  it('GET internal NodeJS route', async done => {

      agent
        .get('/internal')
        .set('Accept', 'application/json')
        .send()
        .expect(200)
        .end((err, res) => {
          if (err) {
            return done(err);
          }
          expect(res.status).toBe(200);
          return done();
        });
  });

});

ОБНОВЛЕНИЕ:

Я попытался удалить NODE_TLS_REJECT_UNAUTHORIZED и установить для параметра rejectUnauthorized значение false в конфигурации агента ax ios, но по-прежнему та же проблема. Соединение работает при использовании приложения через браузер, но работает с супертестом.

  const agent = new https.Agent({
    rejectUnauthorized: false
  });

  const options = {
    url: url,
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/json',
      'Authorization': `Bearer ${requestOptionsData.jwt}`,
      'Host': process.env.ADMIN_API_BASE_URL
    },
    method: requestOptionsData.method || `GET`,
    httpsAgent: agent
  }

Вот ошибка с этой конфигурацией агента:

Error: Error: self signed certificate
          at Object.dispatchError (/home/node/app/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:54:19)
          at EventEmitter.<anonymous> (/home/node/app/node_modules/jsdom/lib/jsdom/living/xmlhttprequest.js:675:20)
          at EventEmitter.emit (events.js:323:22)
          at Request.<anonymous> (/home/node/app/node_modules/jsdom/lib/jsdom/living/xhr-utils.js:384:47)
          at Request.emit (events.js:311:20)
          at Request.onRequestError (/home/node/app/node_modules/request/request.js:877:8)
          at ClientRequest.emit (events.js:311:20)
          at TLSSocket.socketErrorListener (_http_client.js:426:9)
          at TLSSocket.emit (events.js:311:20)
          at emitErrorNT (internal/streams/destroy.js:92:8) undefined
    console.error controllers/http.ctrl.js:50

1 Ответ

0 голосов
/ 15 апреля 2020

Мне удалось решить эту проблему с помощью решения этой проблемы github.

Я решил это, добавив testEnvironment: 'node', в файл jest.config. js.

https://github.com/axios/axios/issues/1180

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...