Заголовки ответов «Управление доступом-Разрешить учетные данные», «Управление доступом-Разрешить происхождение» отображаются для локального, но не для контейнера docker

#node.js #laravel #docker #nginx #cors

#node.js #ларавель #докер #nginx #корс

Вопрос:

кто-нибудь может помочь мне решить эту проблему?

Я запускаю серверную часть php Laravel с fortify и sanctum для аутентификации. У меня также есть интерфейс React, который выполняет вызовы api для этого бэкенда, оба из которых являются докеризованными. Если я запускаю php-сервер локально, проблем с CORs не возникает. Но как только серверная часть запускается через контейнер docker, возникает следующая проблема: Проблема CORS

 Access to XMLHttpRequest at 'http://localhost:8000/api/tickets' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.  

На вкладке сеть мы видим, что URL-адрес запроса не содержит следующих полей в заголовках ответов: «Управление доступом-Разрешить-Учетные данные», «Управление доступом-Разрешить-Происхождение». Есть ли способ, чтобы два контейнера docker разрешали CORs?

Что я пробовал:

  • Настройка контейнера NGINX для работы в качестве обратного прокси-сервера, включая добавление полей в:
 location / {  resolver 127.0.0.11;   add_header 'Access-Control-Allow-Origin' '*';  add_header 'Access-Control-Allow-Credentials' 'true';  add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';  add_header 'Access-Control-Allow-Headers' 'Accept,Content-Type';   set $nextjs nextjs_upstream;  proxy_pass http://$nextjs;  }  
  • Добавлены все необходимые поля CORS в мои файлы конфигурации для сервера, т. е. cors.php файл.
 lt;?php  return [   'paths' =gt; ['*', 'api/*', 'login', 'logout', 'sanctum/csrf-cookie', 'api/tickets'],   'allowed_methods' =gt; ['*'],   'allowed_origins' =gt; ['http://localhost','*'],   'allowed_origins_patterns' =gt; [],   'allowed_headers' =gt; ['X-Custom-Header', 'Upgrade-Insecure-Requests','*'],   'exposed_headers' =gt; [],   'max_age' =gt; 0,   'supports_credentials' =gt; true,  ];  

Примечание: Эта попытка, в частности, может иметь смысл, поскольку localhost в «allowed_origins» относится к хосту внутри контейнера, но как бы мы изменили его, чтобы он находился вне контейнера? Будет ли это IP-адрес этого контейнера или что-то в этом роде?

  • Добавлены дополнительные установки в файл настройки php: "amp;amp; a2enmod headers amp;amp; sed -ri -e 's/^([ t]*)(lt;/VirtualHostgt;)/1tHeader set Access-Control-Allow-Origin "*"n12/g' /etc/apache2/sites-available/*.conf"

Интересно, что мои маршруты входа/выхода из системы не сталкиваются с той же ошибкой CORS, которая беспокоит мой маршрут: api/билеты, но это не относится к делу, поскольку похоже, что это скорее проблема с контейнерами docker, пытающимися взаимодействовать.

Note: localhost has no port since NGINX serves the yarn/npm build.

Laravel Dockerfile:

 # The base image FROM php:8.0.2 as base # Install system dependencies i.e. Zip , curl: RUN apt-get update amp;amp; apt-get install -y   zip   unzip  # Get extensions for PHP amp; Install Postgres RUN apt-get install -y libpq-dev   amp;amp; docker-php-ext-configure pgsql -with-pgsql=/usr/local/pgsql   amp;amp; docker-php-ext-install pdo pdo_pgsql pgsql # Get the latest composer: COPY --from=composer:latest /usr/bin/composer /usr/bin/composer  # Copy everything to the working directory COPY . /app  # Set the current working directory WORKDIR /app  # Install dependencies for laravel COPY composer.json ./ RUN composer install  # Move the exec file to our workdir and give permissions COPY docker-init.sh /usr/local/bin/ RUN chmod  x /usr/local/bin/docker-init.sh  # Expose internal port which will be mapped EXPOSE 8000 # Run our server ENTRYPOINT [ "docker-init.sh" ]  

Frontend Dockerfile:

 FROM node:alpine as build  # Set the current working directory WORKDIR /usr/app  # Install PM2 globally RUN npm install --global pm2  # Get all dependencies COPY package*.json ./  # Copy everything to the working directory RUN npm install --force --production RUN yarn add --dev typescript @types/react COPY . ./  RUN npm run build  # Expose internal port which will be mapped EXPOSE 3000  USER node  CMD [ "pm2-runtime", "npm", "--", "start" ]  

Файл докера Nginx:

 # Prod environment FROM nginx:alpine  # Remove any existing config files RUN rm /etc/nginx/conf.d/*  # Copy config files COPY ./default.conf /etc/nginx/conf.d/  EXPOSE 80  CMD ["nginx", "-g", "daemon off;"]  

docker-init.sh

 #!/bin/bash  # Exit immediately if a pipeline returns a non zero status set -e  # Change to our working directory cd /app  # php artisan migrate # Serve for all IPv4 addresses: php artisan serve --host=0.0.0.0 --port=8000  

Спасибо за помощь, ребята

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

1. Вы не можете разрешить учетные данные и * источники

2. Хорошо, я удалил это из файла nginx conf. Та же ошибка, но не думайте, что проблема здесь в NGINX 🙁

3. К вашему сведению, это также есть в вашем cors.php файле. Итак, ваша служба Laravel работает в контейнере, который предоставляет порт 8000? Если вы правильно настроили CORS в этой службе, вам не понадобится обратный прокси-сервер

4. Так я бы установил «supports_credentials» в значение false? И да, сервер laravel работает в отдельном файле Dockerfile, называемом через docker-compose. Я отредактировал свой оригинальный пост, чтобы включить его

5. «Так я бы установил «supports_credentials» в значение false?» … Это зависит от того, хотите ли вы поддерживать файлы cookie запросов разных источников или нет. Если да, то сохраните его true и не используйте * в разрешенных источниках

Ответ №1:

Решил эту проблему, пришлось внести изменения в app/Http/kernel.php файл. В основном в строках я должен был сделать » веб » и » api » одинаковыми:

 protected $middlewareGroups = [  'web' =gt; [  AppHttpMiddlewareEncryptCookies::class,  IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,  IlluminateSessionMiddlewareStartSession::class,  // IlluminateSessionMiddlewareAuthenticateSession::class,  IlluminateViewMiddlewareShareErrorsFromSession::class,  AppHttpMiddlewareVerifyCsrfToken::class,  IlluminateRoutingMiddlewareSubstituteBindings::class,  ],   'api' =gt; [  EnsureFrontendRequestsAreStateful::class,  'throttle:api',  IlluminateRoutingMiddlewareSubstituteBindings::class,  ], ];  

Становится:

 protected $middlewareGroups = [  'web' =gt; [  AppHttpMiddlewareEncryptCookies::class,  IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,  IlluminateSessionMiddlewareStartSession::class,  // IlluminateSessionMiddlewareAuthenticateSession::class,  IlluminateViewMiddlewareShareErrorsFromSession::class,  AppHttpMiddlewareVerifyCsrfToken::class,  IlluminateRoutingMiddlewareSubstituteBindings::class,  ],   'api' =gt; [  EnsureFrontendRequestsAreStateful::class,  'throttle:api',  IlluminateRoutingMiddlewareSubstituteBindings::class,  AppHttpMiddlewareEncryptCookies::class,  IlluminateCookieMiddlewareAddQueuedCookiesToResponse::class,  IlluminateSessionMiddlewareStartSession::class,  IlluminateViewMiddlewareShareErrorsFromSession::class,  AppHttpMiddlewareVerifyCsrfToken::class,  IlluminateRoutingMiddlewareSubstituteBindings::class,  ], ];