Как включить заголовок CORS allow-origin на сервере Express с помощью swagger-ui

#express #cors #swagger-ui #swagger-2.0 #access-control

#экспресс #cors #swagger-ui #swagger-2.0 #контроль доступа

Вопрос:

Мой сервер API не изменяет и не перезаписывает заголовок Access-Control-Allow-Origin.

У меня есть приложение Angular 2 с API Express / Swagger-UI.

Заголовок Access-Control-Allow-Origin в API не может быть ‘*’, потому что я использую ‘withCredentials’ в своих запросах, и это вызывает ошибку в браузере.

Я использовал ‘cors’ для настройки заголовков CORS. Вот так:

 'use strict';

var configuration = require('./configuration');
var SwaggerExpress = require('swagger-express-mw');
var app = require('express')();
var mongoose = require('mongoose');
var bluebird = require('bluebird');
var bodyParser = require('body-parser');
var jwt = require('jsonwebtoken');
var compression = require('compression');
var cors = require('cors');

app.use(bodyParser.json({ limit: '50mb' }));
app.use(compression());

SwaggerExpress.create(config, function(err, swaggerExpress) {
  if (err) { throw err; }

  swaggerExpress.register(app);
  var port = process.env.PORT || 10010;
  mongoose.Promise = bluebird;
  mongoose.connect(appConfig.dbConection());
  mongoose.connection.on('error', console.error.bind(console, 'connection error: '));
  mongoose.set('debug', true);
  mongoose.connection.once('open', function() {
    app.listen(port);
  })
});
const swaggerUi = require('swagger-ui-express');
const YAML = require('yamljs');
const swaggerDocument = YAML.load('./api/swagger/swagger.yaml');

app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocument));
var allowedOrigins = ['http://localhost:4200', 'http://127.0.0.1:10010'];
app.use(cors({
    origin: (origin, callback) => {
        if (!origin) return callback(null, true);
        if (allowedOrigins.indexOf(origin) === -1) {
            return callback(new Error('The CORS policy for this site does not allow the specified Origin'), false);
        }
        return callback(null, true);
    },
    exposedHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization', 'api_key', 'x-api-key'],
    credentials: true
}));
  

Источник Access-Control-Allow-Origin должен соответствовать массиву разрешенных хостов.

Когда я вызываю API из браузера, он сначала запрашивает ПАРАМЕТРЫ, которые выглядят корректно, вот так:

 Request URL: http://localhost:10010/v1/loginApp
Request Method: OPTIONS
Status Code: 204 No Content
Remote Address: [::1]:10010
Referrer Policy: no-referrer-when-downgrade

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: x-api-key
Access-Control-Allow-Methods: GET,HEAD,PUT,PATCH,POST,DELETE
Access-Control-Allow-Origin: http://localhost:4200
Access-Control-Expose-Headers: Origin,X-Requested-With,Content-Type,Accept,Authorization,api_key,x-api-key
Connection: keep-alive
Content-Length: 0
Date: Thu, 04 Apr 2019 08:25:53 GMT
Vary: Origin, Access-Control-Request-Headers
X-Powered-By: Express

  

Но затем он выполняет запрос GET / POST, а затем у него снова появляются заголовки по умолчанию:

 Request URL: http://localhost:10010/v1/loginApp
Request Method: GET
Status Code: 200 OK
Remote Address: [::1]:10010
Referrer Policy: no-referrer-when-downgrade

Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Access-Control-Expose-Headers: Origin,X-Requested-With,Content-Type,Accept,Authorization,api_key,x-api-key
Content-Length: 770
Content-Type: application/json; charset=utf-8
Date: Thu, 04 Apr 2019 08:25:53 GMT
ETag: W/"302-BwX5DjK/lUY ueP6UZ9TgWOTw/s"
Vary: Origin
X-Powered-By: Express
  

Я думаю, что что-то (возможно, swagger-UI) перезаписывает конфигурацию моих заголовков, но я не могу понять это.

Ответ №1:

Вам необходимо зарегистрировать свое промежуточное программное обеспечение CORS перед обработчиками ПОЛУЧЕНИЯ / ПУБЛИКАЦИИ Swagger.

Запрос ПАРАМЕТРОВ выполняется успешно, потому что Swagger не регистрирует обработчик параметров, поэтому запрос достигает промежуточного программного обеспечения.

Запросы GET / POST завершаются сбоем до того, как обработчики Swagger примут запрос до того, как он достигнет промежуточного программного обеспечения CORS.

Переместите, app.use(cors({... чтобы это было раньше app.use('/api-docs', swaggerUi... .

Комментарии:

1. Привет, Квентин, спасибо за твой ответ. Я попытался переместить настройку cors в начало, и в моем запросе я получил тот же результат.

Ответ №2:

Кажется, что swagger-express-mw поставляется со встроенной поддержкой CORS, см. swagger_controllers в вашем config/default.yaml . У меня была такая же проблема, и я исправил ее, удалив cors оттуда.

Как и вы, я подозреваю, что он перезаписывает Access-Control-Allow-Origin заголовок, но у меня не было времени проверить его должным образом.