Как настроить CORS для API-шлюза и сокетов в микросервисах Spring Boot

Вопрос или проблема

Как настроить CORS для API-шлюза и сокетов в микросервисах Spring Boot

У меня есть приложение на Springboot Microservice. В моем приложении есть 4 микросервиса.

API-шлюз,
управление пользователями,
idm-сервис,
engine-service.

Я использую React в качестве фронтенда.

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

Конфигурация API-шлюза:

cors-configurations:
  '[/**]':
    allowCredentials: true
    allowedOrigins:
      - "http://localhost:3000"
    allowedHeaders: "*"
    allowedMethods:
      - GET
      - POST
      - DELETE
      - PUT
      - OPTIONS
      - PATCH

Я должен добавить allowCredentials: true, чтобы разрешить соединение по веб-сокету, и это работает хорошо.

Конфигурация сокета engine-service:

@Override
  public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint(registryEndpoint).setAllowedOrigins("http://localhost:3000").withSockJS();
  }

Теперь снова мне нужно добавить setAllowedOrigins в конфигурацию веб-сокета. Когда запрос приходит в engine-service, я получаю ошибку следующего вида:

Заголовок 'Access-Control-Allow-Origin' содержит несколько значений 'http://localhost:3000, http://localhost:3000', но разрешено только одно.

Сейчас я не могу найти решение для этого. Все запросы должны проходить через API-шлюз, поэтому мне нужно добавить конфигурацию CORS там, иначе я получу ошибку CORS в API-шлюзе. Если я добавляю setAllowedOrigins в API-шлюз, я получаю ошибку в engine-service.

Можете ли вы подсказать мне, как решить эту ошибку?
Для соединения по веб-сокету, мне следует напрямую взаимодействовать с engine-service, а не проходить через API-шлюз?

Ответ или решение

Конечно! Давайте рассмотрим проблему конфигурации CORS для API Gateway и WebSocket в ваших микросервисах Spring Boot и предложим решение.

Проблема

Вы имеете API Gateway, который выполняет роль прокси-сервера для ваших микросервисов. У вас есть множество CORS настроек и вы сталкиваетесь с проблемой дублирования заголовка Access-Control-Allow-Origin, когда происходит настройка WebSocket соединения из интерфейса React, что приводит к ошибке.

Решение

Чтобы избежать конфликта заголовков и правильно настроить CORS для вашего API Gateway и микросервиса Engine, выполните следующие шаги:

1. Настройка CORS в API Gateway

Ваш API Gateway должен управлять всеми CORS запросами, включая запросы, связанные с WebSocket. Убедитесь, что ваша конфигурация CORS в API Gateway выглядит следующим образом:

cors-configurations:
  '[/**]':
    allowCredentials: true
    allowedOrigins:
      - "http://localhost:3000"
    allowedHeaders: "*"
    allowedMethods:
      - GET
      - POST
      - DELETE
      - PUT
      - OPTIONS
      - PATCH

Это уже правильно, но стоит убедиться, что эти настройки применяются ко всем маршрутам, включая маршруты WebSocket.

2. Удаление setAllowedOrigins из Engine Service

Вам не нужно добавлять setAllowedOrigins в конфигурации WebSocket в вашем EngineService. Вместо этого настройка CORS в вашем API Gateway будет обрабатывать CORS заголовки для начинающегося WebSocket соединения.

Вот как может выглядеть ваш код без setAllowedOrigins:

@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
    registry.addEndpoint(registryEndpoint).setAllowedOrigins("*").withSockJS();
}

Здесь присутствует setAllowedOrigins("*"), но так как CORS уже обрабатывается на стороне API Gateway, может быть даже лучше убрать этот метод или оставить его с *, чтобы гарантировать, что нет конфликтов.

3. Убедитесь в правильной настройке прокси сервера

Ваш API Gateway должен обрабатывать все запросы как CORS, включая запросы WebSocket. Убедитесь, что у вас правильно настроен маршрут в API Gateway для WebSocket:

@Override
public void configure(HttpSecurity http) throws Exception {
    http.cors().and()
        .authorizeRequests()
        .antMatchers("/ws/**").permitAll() // разрешите доступ к WebSocket
        .anyRequest().authenticated();
}

4. Проверьте настройки на стороне клиента

В вашем React приложении убедитесь, что вы корректно инициализируете подключение к WebSocket через API Gateway:

const socket = new SockJS('http://localhost:8080/ws'); // используйте URL вашего API Gateway
const stompClient = Stomp.over(socket);
stompClient.connect({}, (frame) => {
    console.log('Connected: ' + frame);
});

Заключение

Эти шаги должны помочь вам настроить CORS между вашим API Gateway и микросервисом Engine, устранив ошибки, связанные с Access-Control-Allow-Origin. Убедившись, что весь трафик WebSocket проходит через API Gateway, вы избежите конфликтов и дублирования заголовков CORS.

Если у вас возникнут дополнительные вопросы или потребуется дальнейшая помощь, не стесняйтесь спрашивать!

Оцените материал
Добавить комментарий

Капча загружается...