diff --git a/config-repo/pcp-gateway-service.yaml b/config-repo/pcp-gateway-service.yaml index 57ec2d5..af1d5ac 100644 --- a/config-repo/pcp-gateway-service.yaml +++ b/config-repo/pcp-gateway-service.yaml @@ -10,6 +10,19 @@ spring: server: # WebFlux-вариант Spring Cloud Gateway (Boot 4 / Spring Cloud 2025.1). webflux: + # CORS теперь живёт ТОЛЬКО здесь — единая точка на edge. Раньше дублировался + # per-service (pcp-ui-service/WebConfig.kt), но после сворачивания фронта на + # gateway браузер ходит к бэкендам строго через него. Страховка от cross-origin + # к самому gateway (dev напрямую, LAN-адрес рабочей станции): allowedOriginPatterns + # "*" совместим с allowCredentials=true (в отличие от allowedOrigins "*"). + globalcors: + cors-configurations: + '[/**]': + allowedOriginPatterns: "*" + allowedMethods: "*" + allowedHeaders: "*" + allowCredentials: true + maxAge: 3600 routes: # --- Доменные сервисы. Префикс /api/pcp- СРЕЗАЕТСЯ (StripPrefix=2 убирает # 2 сегмента: api + pcp-), т.е. /api/pcp-tgu/api/plans -> бэкенд /api/plans. diff --git a/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/configuration/WebConfig.kt b/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/configuration/WebConfig.kt deleted file mode 100644 index 11631c8..0000000 --- a/services/pcp-ui-service/src/main/kotlin/space/nstart/pcp/slots_service/configuration/WebConfig.kt +++ /dev/null @@ -1,62 +0,0 @@ -package space.nstart.pcp.slots_service.configuration -import org.springframework.context.annotation.Bean -import org.springframework.context.annotation.Configuration -import org.springframework.web.cors.CorsConfiguration -import org.springframework.web.cors.UrlBasedCorsConfigurationSource -import org.springframework.web.filter.CorsFilter -import org.springframework.web.servlet.config.annotation.CorsRegistry -import org.springframework.web.servlet.config.annotation.WebMvcConfigurer - - -@Configuration -class WebConfig : WebMvcConfigurer { - - override fun addCorsMappings(registry: CorsRegistry) { - // Внутренний ops-инструмент: UI открывают с разных хостов/IP (localhost, - // LAN-адрес рабочей станции, прод-сборка). Любой явный список origin'ов рано - // или поздно не совпадает с фактическим адресом UI → POST/PUT/DELETE отбивается - // как «Invalid CORS request» (same-origin GET проходит, т.к. идёт без Origin). - // Поэтому разрешаем любой origin. allowedOriginPatterns("*") совместим с - // allowCredentials=true (в отличие от allowedOrigins("*")). - registry.addMapping("/**") - .allowedOriginPatterns("*") - .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH") - .allowedHeaders("*") - .allowCredentials(true) - .maxAge(3600) - } - - // Альтернативный вариант через CorsFilter - @Bean - fun corsFilter(): CorsFilter { - val source = UrlBasedCorsConfigurationSource() - val config = CorsConfiguration().apply { - allowCredentials = true - // Любой origin — см. комментарий в addCorsMappings. - allowedOriginPatterns = listOf("*") - // Разрешенные заголовки - allowedHeaders = listOf( - "Origin", - "Content-Type", - "Accept", - "Authorization", - "X-Requested-With", - "Access-Control-Request-Method", - "Access-Control-Request-Headers" - ) - // Разрешенные методы - allowedMethods = listOf( - "GET", "POST", "PUT", "DELETE", "OPTIONS", "PATCH", "HEAD" - ) - // Заголовки, доступные клиенту - exposedHeaders = listOf( - "Access-Control-Allow-Origin", - "Access-Control-Allow-Credentials" - ) - maxAge = 3600L - } - - source.registerCorsConfiguration("/**", config) - return CorsFilter(source) - } -}