Совместное использование ресурсов между источниками (CORS) часто может стать камнем преткновения при разработке и развертывании приложений с отдельными серверными и внешними интерфейсами. Эта статья призвана раскрыть тайну этой концепции и представить решение, использующее Nginx в качестве обратного прокси-сервера.

Сказка о двух владениях

Рассмотрим такой сценарий: вы разрабатываете веб-приложение с интерфейсом ReactJS и сервером ExpressJS. Кодовая база организована в виде монорепозитория, что указывает на то, что и внешний, и внутренний код находятся в одном и том же репозитории. Для развертывания вы решаете разместить свой интерфейс на `domainA.com`, а серверную часть на `domainB.com`.

Однако это приводит к проблеме — ваш интерфейс не может общаться с вашим сервером из-за ограничений CORS. Ваш браузер видит домены `domainA.com` и `domainB.com` как отдельные источники и блокирует любые попытки внешнего интерфейса получить ресурсы из внутреннего интерфейса, рассматривая это как потенциальную угрозу безопасности.

Итак, как обойти это, не ставя под угрозу безопасность и не прибегая к «подстановочным» настройкам CORS?

Войдите в Nginx: решение для обратного прокси

Nginx, популярный веб-сервер с открытым исходным кодом, предоставляет мощную функцию, известную как обратное проксирование. Это означает, что Nginx может принимать клиентские запросы и на основе определенных правил перенаправлять эти запросы на соответствующие серверы (в нашем случае на внешний или внутренний сервер).

Используя Nginx в качестве обратного прокси-сервера, вы можете полностью избежать проблем с CORS. Решение включает в себя настройку Nginx для обслуживания вашего интерфейса и сервера из одного домена, что устраняет проблему перекрестного происхождения.

Вот как это работает:

- Внешний интерфейс (ReactJS): настройте Nginx для предоставления внешнего интерфейса непосредственно пользователям, которые посещают `domainA.com`. Это включает в себя хранение статических файлов (HTML, CSS, JavaScript), созданных React, на сервере, где работает Nginx.

- Бэкэнд (ExpressJS): Настройте Nginx для перенаправлять запросы, сделанные на `domainA.com/api`, на ваш внутренний сервер. Независимо от того, находится ли ваш внутренний сервер на том же компьютере или на другом, Nginx будет перенаправлять на него все запросы `/api`.

С точки зрения браузера пользователя , все запросы (как к интерфейсу, так и к серверу) направляются в один и тот же домен (`domainA.com`). Эта настройка устраняет запросы из разных источников, поэтому нет проблем с CORS.

Перенастройка Nginx

Давайте углубимся в практическую сторону вопроса — как настроить Nginx для достижения этой цели? Вот пример конфигурации Nginx:

server {
 listen 80;
 server_name domainA.com;
location / {
 # assuming your frontend files are in /var/www/frontend
 root /var/www/frontend;
 try_files $uri /index.html;
 }
location /api {
 # assuming your Express server is running on the same machine
 # and listening on port 3000, if it's on a different machine
 # replace 'localhost' with the appropriate IP address
 proxy_pass http://localhost:3000;
 proxy_http_version 1.1;
 proxy_set_header Upgrade $http_upgrade;
 proxy_set_header Connection 'upgrade';
 proxy_set_header Host $host;
 proxy_cache_bypass $http_upgrade;
 }
}

Блок `location/` предназначен для вашего внешнего интерфейса. Он обслуживает файлы из каталога `/var/www/frontend`. Блок `location /api` предназначен для вашего бэкенда. Он перенаправляет запросы на сервер ExpressJS, работающий по адресу `http://localhost:3000`.

Путь Монорепо

Монорепозиторий (сокращение от монолитный репозиторий) — это

стратегия разработки программного обеспечения, при которой код для многих проектов хранится в одном репозитории. Он популярен в крупномасштабных проектах, поскольку упрощает обмен кодом и управление зависимостями.

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

С приведенной выше конфигурацией развертывание становится простым — и интерфейсом, и сервером можно управлять с одного и того же сервера с помощью Nginx, что снижает сложность и сохраняет вашу кодовую базу в чистоте и порядке.

Вынос

CORS — необходимая, но часто сложная часть веб-разработки. Используя возможности Nginx в качестве обратного прокси-сервера, вы можете более легко создавать и развертывать свои приложения, устраняя проблемы CORS и сохраняя при этом хорошо структурированную кодовую базу в монорепозитории. Помните, ключ в том, чтобы иметь единый источник для вашего интерфейса и сервера — все под эгидой одного и того же домена.

Примечание. В этом руководстве предполагается, что вы уже знакомы с Nginx. Если вам неудобно настраивать его самостоятельно, рассмотрите возможность работы с инженером DevOps или кем-то с соответствующим опытом. Крайне важно правильно настроить сервер, чтобы избежать потенциальных проблем с безопасностью и производительностью.