Ошибки CORS с Symfony 4 и Nelmio CORS Bundle

Я пытался выяснить, почему у меня возникают проблемы CORS с моим приложением API Symfony 4, которое я только что развернул на своем сервере Apache, и не могу понять проблему.

конфиг/пакеты/nelmio_cors.yaml

nelmio_cors:
    defaults:
        origin_regex: true
        allow_origin: ['%env(CORS_ALLOW_ORIGIN)%']
        allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
        allow_headers: ['Content-Type', 'Authorization']
        max_age: 3600
    paths:
        '^/': ~

.env

...
CORS_ALLOW_ORIGIN=/*/
...

Все ответы на запросы, которые я отправляю из внешнего приложения localhost в этот API, не содержат заголовка Access-Control-Allow-Origin, и я получаю стандартную ошибку;

Access to XMLHttpRequest at 'http://my-api.com/foo' from origin 'http://localhost:4200' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

Никакие специальные заголовки не отправляются, и на данный момент я установил разрешенное регулярное выражение источника на «все», поэтому я не могу понять, что вызывает здесь проблему. Я даже проверил в кеше, чтобы убедиться, что источник правильно извлекается из переменных env, что так и есть. Если для помощи требуется другой контекст/контент файла, пожалуйста, дайте мне знать!

Вы уверены в своей переменной CORS_ALLOW_ORIGIN. Вы пробовали CORS_ALLOW_ORIGIN=* ?

Florian Hermann 06.02.2019 10:32

@FlorianHermann переменная интерпретируется как регулярное выражение, однако да, я пробовал оба значения.

Chris Brown 07.02.2019 13:12
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Symfony Station Communiqué - 17 февраля 2023 г
Symfony Station Communiqué - 17 февраля 2023 г
Это коммюнике первоначально появилось на Symfony Station , вашем источнике передовых новостей Symfony, PHP и кибербезопасности.
Управление ответами api для исключений на Symfony с помощью KernelEvents
Управление ответами api для исключений на Symfony с помощью KernelEvents
Много раз при создании api нам нужно возвращать клиентам разные ответы в зависимости от возникшего исключения.
6
2
9 183
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Зачем тебе нельмио?

У вас может быть простой прослушиватель событий (на ядро.event_subscriber), добавляющий эти заголовки.

namespace App\EventListener\HttpKernel;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\Event\FilterResponseEvent;

class CorsSubscriber implements EventSubscriberInterface
{

    public static function getSubscribedEvents(): array
    {
        return [
            KernelEvents::RESPONSE => 'onResponse'
        ];
    }

    public function onResponse(FilterResponseEvent $filterResponseEvent)
    {
        $response = $filterResponseEvent->getResponse();
        $response->headers->set('Access-Control-Allow-Origin', '*');
    }
}

Зарегистрируйте его как kernel.event_subscriber

    app.http_kernel.cors_subscriber:
        class: App\EventListener\HttpKernel\CorsSubscriber
        tags:
            - { name: kernel.event_subscriber }

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

Chris Brown 02.02.2019 19:02

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

CORS_ALLOW_ORIGIN=^http://(.*:8080|localhost:4200)$

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

CORS_ALLOW_ORIGIN=^.*$

Ваша проблема в том, что вы решили использовать регулярное выражение (origin_regex: true), но не указали допустимый шаблон.

Если вы хотите использовать origin_regex: true, вам следует указать допустимый шаблон, например .* или ^.*$.

Если вы не хотите использовать регулярное выражение, опустите настройку origin_regex (или установите для нее значение false) и просто используйте * в качестве значения CORS_ALLOW_ORIGIN.

Даже с этим предложенным изменением это не имеет значения, я предполагаю, что есть что-то не связанное с этим, что странно.

Chris Brown 16.02.2019 18:24
Ответ принят как подходящий

Я решил проблему, и хотя на первый взгляд она была связана с конфигурацией CORS, на самом деле это была неправильная конфигурация проекта на сервере.

TL; DR заключается в том, что в проекте отсутствовал файл .htaccess, который мне не требовался при разработке из-за использования Valet — следуя инструкциям здесь, проблема была решена.

И каково содержимое .htacess?

ALFA 23.04.2019 15:28

@ALFA это по ссылке в ответе

Chris Brown 24.04.2019 16:31

Другие вопросы по теме