Рубрики
Без рубрики

Обработка CORS с Node.js

В этой статье мы настроим CORS с Express и Node.js и настроить его для одноразовых маршрутов, все маршруты и разрешить динамическую конфигурацию.

Автор оригинала: Janith Kasun.

Вступление

В этой статье мы посмотрим на то, что такое CORS, как вы можете настроить CORS с Express и как настроить промежуточное программное обеспечение CORS к вашим потребностям.

Что такое CORS.

CORS Снаряжение для Распределение ресурсов с перекрестным происхождением Отказ Это механизм, позволяющий разрешать или ограничивать запрошенные ресурсы на веб-сервере зависят от того, где был инициирован HTTP-запрос.

Эта политика используется для обеспечения определенного веб-сервера от доступа к другому веб-сайту или домену. Например, только разрешенные домены смогут получить доступ к проведенным файлам на сервере, таком как таблица стилей, изображение или сценарий.

Если вы в настоящее время на http://example.com/page1 И вы ссылаетесь на изображение из http://image.com/myimage.jpg Вы не сможете получить это изображение, если http://image.com позволяет обменять перекрестное происхождение с http://example.com Отказ

Есть заголовок HTTP под названием Происхождение В каждом HTTP-запросе. Он определяет, откуда возникл запрос домена. Мы можем использовать информацию заголовка для ограничения или разрешения ресурсов нашего веб-сервера для их защиты.

По умолчанию запросы от любого другого происхождения будут ограничены браузером.

Например, пока вы все еще находитесь на этапе разработки – если вы используете библиотеку Frontend, такие как RECT, ваше приложение для переднего конца будет подано на http://localhost: 3000 Отказ Между тем, ваш экспресс-сервер может работать на другом порту, например http://localhost: 2020 Отказ

Из-за этого вам нужно будет разрешать CORS между этими серверами.

Если вы видите эту общую ошибку в консоли браузера. Ограничения COR могут быть проблема:

Chrome Cors.

CORS действительно полезен, когда вы предлагаете общедоступную API и хотели бы контролировать доступ к определенным ресурсам и как люди используют их.

Кроме того, если вы хотите использовать свои собственные API или файлы на другой веб-странице, вы можете просто настроить CORS, чтобы позволить, пока все еще блокируя другие.

Настройка CORS с Express

Давайте начнем со свежим проектом. Мы сделаем каталог для него, введите его и запустите NPM init С настройками по умолчанию:

$ mkdir myapp
$ cd myapp
$ npm init -y

Затем давайте установим необходимые модули. Мы будем использовать Экспресс и CORS промежуточное программное обеспечение:

$ npm i --save express
$ npm i --save cors

Затем начнем создать экспресс-приложение с двумя маршрутами, чтобы продемонстрировать, как работает CORS.

Мы сделаем файл, называемый index.js который действует как веб-сервер, с парой обработчиков запросов:

const express = require('express');
const cors = require('cors');

const app = express();

app.get('/', (req, res) => {
    res.json({
        message: 'Hello World'
    });
});

app.get('/:name', (req, res) => {
    let name = req.params.name;

    res.json({
        message: `Hello ${name}`
    });
});

app.listen(2020, () => {
    console.log('server is listening on port 2020');
});

Давайте запустим приложение и сервер:

$ node index.js

Теперь, если вы идете в http://localhost: 2020/ – сервер должен вернуть сообщение JSON:

{
  "message": "Hello World"
}

В качестве альтернативы, если вы идете на http://localhost: 2020/что-то Тебе следует увидеть:

{
  "message": "Hello something"
}

Включить все запросы CORS

Если вы хотите включить CORS для всех запросов, вы можете просто использовать CORS промежуточное программное обеспечение перед настройкой ваших маршрутов:

const express = require('express');
const cors = require('cors');

const app = express();

app.use(cors())

......

Это позволит доступ к доступе все маршруты в любом месте в Интернете, если это то, что вам нужно. Таким образом, в нашем примере обе маршруты будут доступны для каждого домена.

Например, если наш сервер работает на http://www.example.com И служит контент, такое как изображения – мы позволяем другим доменам, таким как http://www.differentdomain.com обратиться к контенту из http://www.example.com Отказ

Таким образом, веб-страница на http://www.differentdomain.com Можно использовать наш домен в качестве источника для изображения:


Включить CORS для одного маршрута

Но если вам нужен определенный маршрут, чтобы быть доступным, а не другие маршруты, вы можете настроить CORS В определенном маршруте как промежуточное программное обеспечение вместо того, чтобы настроить его на все приложение:

app.get('/', cors(), (req, res) => {
    res.json({
        message: 'Hello World'
    });
});

Это позволит иметь определенный маршрут для доступов любым доменом. Так что в вашем случае только / Маршрут будет доступен для каждого домена. /: имя Маршрут будет доступен только для запросов, которые инициируются в том же домене, что и API, который является http://localhost: 2020 в нашем случае.

Например, если вы попытаетесь отправить запрос Fetch на / путь от другого происхождения – это будет успешно, и вы получите Здравствуйте, мир сообщение как ответ:

fetch('http://localhost:2020/')
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(err => console.error(err));

Вы должны увидеть ответ с сервера успешно войти в консоль, если вы запустите этот код:

{
    message: 'Hello World'
}

Но если вы попытаетесь получить доступ к любому другому пути, кроме корневого пути, такого как http://localhost: 2020/имя или http://localhost: 2020/img/cat.png Этот запрос будет заблокирован браузером:

fetch('http://localhost:2020/name/janith')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

Вы должны увидеть следующую ошибку, если вы попытаетесь запустить этот код в другом веб-приложении:

Ошибка консоли

Настроить CORS с опциями

Вы также можете использовать параметры конфигурации с помощью COR, чтобы настроить это дальше. Вы можете использовать конфигурацию, чтобы разрешить доступ к одному домену или доступу поддоменов, настроить HTTP-методы, которые разрешены такие как Получить и Пост в зависимости от ваших требований.

Вот как вы можете разрешить доступ к одному домену, используя варианты CORS:

var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // For legacy browser support
}

app.use(cors(corsOptions));

Если вы настраиваете доменное имя в начале происхождения – сервер позволит CORS из сконфигурированного домена. Так что API будет доступен из http://localhost: 8080 в нашем случае и заблокирован для других доменов.

Если мы отправим Получить Запрос, доступ к любому пути должен работать, поскольку параметры применяются на уровне APP, а не на уровне функции.

Итак, если мы запустим следующий код и отправьте запрос от http://localhost: 8080 к http://localhost: 2020 :

fetch('http://localhost:2020/')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

// Or

fetch('http://localhost:2020/name/janith')
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(err => console.error(err));

Нам разрешено получить информацию из этого приложения и домена.

Вы также можете настроить разрешенные методы HTTP, если хотите:

var corsOptions = {
    origin: 'http://localhost:8080',
    optionsSuccessStatus: 200 // For legacy browser support
    methods: "GET, PUT"
}

app.use(cors(corsOptions));

Если мы отправим Пост Запрос от http://localhost: 8080 , это будет заблокировано браузером только Получить и Поставить поддерживаются:

fetch('http://localhost:2020', {
  method: 'POST',
  body: JSON.stringify({name: "janith"}),
})
.then(response => response.json())
.then(data => console.log(data))
.catch(err => console.error(err));

Чтобы увидеть полный список вариантов конфигурации, пожалуйста, обратитесь к официальной документации.

Настройка динамических чиновков CORS с использованием функции

Если конфигурации не удовлетворяют вашим требованиям, вы можете создать свою функцию для настройки CORS.

Например, давайте предположим, что вы хотите разрешить делиться CORS для .jpg Файлы http://something.com и http://example.com :

const allowlist = ['http://something.com', 'http://example.com'];

    const corsOptionsDelegate = (req, callback) => {
    let corsOptions;

    let isDomainAllowed = whitelist.indexOf(req.header('Origin')) !== -1;
    let isExtensionAllowed = req.path.endsWith('.jpg');

    if (isDomainAllowed && isExtensionAllowed) {
        // Enable CORS for this request
        corsOptions = { origin: true }
    } else {
        // Disable CORS for this request
        corsOptions = { origin: false }
    }
    callback(null, corsOptions)
}

app.use(cors(corsOptionsDelegate));

Функция обратного вызова примет два параметра. Первый – это ошибка, где мы прошли null а второй – варианты, где мы прошли {Происхождение: false} Отказ Второй параметр может быть много вариантов, которые построены с использованием Запрос объект из обработчика Express запрос.

Так что веб-приложение, которое размещено на http://something.com или http://example.com сможет обратиться к изображению с .jpg Расширение с сервера, как мы настроили в нашей пользовательской функции.

Таким образом, следующее наложение изображений будет успешным с любого из них:


Но следующее приложение будет заблокировано:


Список загрузки разрешенного происхождения от как источник данных

Вы можете использовать также использовать список разрешенных доменов из базы данных или использование любого источника данных о сохранении данных, чтобы разрешить CORS:

var corsOptions = {
    origin: function (origin, callback) {
        // Loading a list of allowed origins from the database
        // Ex.. origins = ['http://example.com', 'http//something.com']
        database.loadOrigins((error, origins) => {
            callback(error, origins);
        });
    }
}

app.use(cors(corsOptions));

Заключение

В этой статье мы охватываем то, что такое CORS и как вы можете настроить его с Express. Затем мы настроили CORS для всех запросов, для определенных запросов, дополнительных параметров и ограничений, а также определенные пользовательские функции для динамической конфигурации CORS.