1. Обзор
В предыдущем посте мы узнали о спецификации совместного использования ресурсов между источниками (CORS) и о том , как ее использовать в Spring.
В этом кратком руководстве мы настроим аналогичную конфигурацию CORS с помощью Spring 5 WebFlux framework .
Прежде всего, мы посмотрим, как мы можем включить этот механизм в API на основе аннотаций.
Затем мы проанализируем, как включить его во всем проекте в качестве глобальной конфигурации или с помощью специального WebFilter .
2. Включение CORS для аннотированных элементов
Пружина обеспечивает @CrossOrigin аннотация для включения запросов CORS на классы контроллеров и/или методы обработчиков.
2.1. Использование @CrossOrigin в методе обработчика запросов
Давайте добавим эту аннотацию к нашему сопоставленному методу запроса:
@CrossOrigin @PutMapping("/cors-enabled-endpoint") public MonocorsEnabledEndpoint() { // ... }
Мы будем использовать WebTestClient (как мы объяснили в разделе ‘4. Тестирование этого поста ) для анализа ответа, который мы получаем от этой конечной точки:
ResponseSpec response = webTestClient.put() .uri("/cors-enabled-endpoint") .header("Origin", "http://any-origin.com") .exchange(); response.expectHeader() .valueEquals("Access-Control-Allow-Origin", "*");
Кроме того, мы можем опробовать предполетный запрос, чтобы убедиться, что конфигурация CORS работает должным образом:
ResponseSpec response = webTestClient.options() .uri("/cors-enabled-endpoint") .header("Origin", "http://any-origin.com") .header("Access-Control-Request-Method", "PUT") .exchange(); response.expectHeader() .valueEquals("Access-Control-Allow-Origin", "*"); response.expectHeader() .valueEquals("Access-Control-Allow-Methods", "PUT"); response.expectHeader() .exists("Access-Control-Max-Age");
Аннотация @CrossOrigin имеет следующую конфигурацию по умолчанию:
- Разрешает все источники (это объясняет значение ” * ” в заголовке ответа)
- Разрешает все заголовки
- Все методы HTTP, сопоставленные методом обработчика, разрешены
- Учетные данные не включены
- Значение “Максимальный возраст” составляет 1800 секунд (30 минут)
Однако любое из этих значений может быть переопределено с помощью параметров аннотаций.
2.2. Использование @CrossOrigin на контроллере
Эта аннотация также поддерживается на уровне класса, и она повлияет на все его методы.
В случае, если конфигурация уровня класса не подходит для всех наших методов, мы можем аннотировать оба элемента, чтобы получить желаемый результат:
@CrossOrigin(value = { "http://allowed-origin.com" }, allowedHeaders = { "Baeldung-Allowed" }, maxAge = 900 ) @RestController public class CorsOnClassController { @PutMapping("/cors-enabled-endpoint") public MonocorsEnabledEndpoint() { // ... } @CrossOrigin({ "http://another-allowed-origin.com" }) @PutMapping("/endpoint-with-extra-origin-allowed") public Mono corsEnabledWithExtraAllowedOrigin() { // ... } // ... }
3. Включение CORS в глобальной конфигурации
Мы также можем определить глобальную конфигурацию CORS, переопределив addCorsMappings() способ получения WebFluxConfigurer реализация.
Кроме того, реализация нуждается в аннотации @EnableWebFlux для импорта конфигурации веб-потока Spring в обычном приложении Spring. Если мы используем Spring Boot, то эта аннотация нужна нам только в том случае, если мы хотим переопределить автоматическую настройку:
@Configuration @EnableWebFlux public class CorsGlobalConfiguration implements WebFluxConfigurer { @Override public void addCorsMappings(CorsRegistry corsRegistry) { corsRegistry.addMapping("/**") .allowedOrigins("http://allowed-origin.com") .allowedMethods("PUT") .maxAge(3600); } }
В результате мы включаем обработку запросов из разных источников для этого конкретного шаблона пути.
Конфигурация по умолчанию аналогична конфигурации @CrossOrigin , но разрешены только методы GET , HEAD и POST .
Мы также можем объединить эту конфигурацию с локальной:
- Для атрибутов с несколькими значениями результирующая конфигурация CORS будет дополнением каждой спецификации
- С другой стороны, локальные значения будут иметь приоритет над глобальными для однозначных значений
Однако использование этого подхода неэффективно для функциональных конечных точек.
4. Включение CORS с помощью веб-фильтра
Лучший способ включить CORS на функциональных конечных точках-это использовать Вебфильтр .
Как мы видели в этом посте , мы можем использовать Веб-фильтр s для изменения запросов и ответов, сохраняя при этом реализацию конечных точек нетронутой.
Пружина обеспечивает встроенный CorsWebFilter чтобы легко справляться с конфигурациями перекрестного происхождения:
@Bean CorsWebFilter corsWebFilter() { CorsConfiguration corsConfig = new CorsConfiguration(); corsConfig.setAllowedOrigins(Arrays.asList("http://allowed-origin.com")); corsConfig.setMaxAge(8000L); corsConfig.addAllowedMethod("PUT"); corsConfig.addAllowedHeader("Baeldung-Allowed"); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", corsConfig); return new CorsWebFilter(source); }
Это также эффективно для аннотированных обработчиков, но его нельзя комбинировать с более мелкозернистой конфигурацией @CrossOrigin .
Мы должны иметь в виду, что конфигурация Cors не имеет конфигурации по умолчанию.
Таким образом, если мы не определим все соответствующие атрибуты, реализация CORS будет в значительной степени ограничительной.
Простым способом установки значений по умолчанию является использование применить значения Разрешения По Умолчанию() метод на объекте.
5. Заключение
В заключение мы ознакомились с очень короткими примерами того, как включить CORS в нашем веб-сервисе на основе потока.
Мы видели разные подходы, поэтому все, что нам сейчас нужно сделать, это проанализировать, какой из них лучше всего соответствует нашим требованиям.
Мы можем найти множество примеров в нашем репозитории GitHub , а также тестовые случаи, в которых мы анализируем большинство крайних случаев, связанных с этой темой.