Keycloak 21集成React与Spring Gateway的CORS问题及修复咨询
解决React + Keycloak 21 + Spring Boot网关的CORS问题
一、Keycloak 21的CORS配置(解决初始跳转错误)
Keycloak 21的CORS控制逻辑和旧版不同,需在客户端配置中直接设置:
- 登录Keycloak管理控制台,进入你的
admin_console_realm - 找到
admin_console_client客户端,进入Settings标签页 - 滚动到Access Settings区域:
Valid Redirect URIs:添加React应用的完整域名(带通配符),比如https://xxxxxxx-xi.vercel.app/*、https://main.dyyfxsm3lnw8e.amplifyapp.com/*,同时保留Spring Boot网关的回调地址http://ip/login/oauth2/code/keycloak(注意协议要和实际部署一致)Web Origins:填写允许跨域的来源,可直接填具体的React域名,或用*(生产环境建议指定具体域名)
- 保存配置即可生效(无需重启Keycloak)
二、修复Nginx配置中的CORS错误(解决mode头不允许问题)
你的Nginx配置存在两个核心问题:一是启用Allow-Credentials时不能用*作为允许来源;二是未明确允许mode请求头。修改后的配置如下:
server { server_name api2.domain.org; index index.html index.htm; access_log /var/log/nginx/bmiapp.log; error_log /var/log/nginx/bmiapp-error.log error; location / { # 处理OPTIONS预请求 if ($request_method = 'OPTIONS') { # 指定允许的React域名,多个用逗号分隔 add_header Access-Control-Allow-Origin 'https://main.dyyfxsm3lnw8e.amplifyapp.com,https://xxxxxxx-xi.vercel.app' always; add_header Access-Control-Allow-Headers 'Content-Type,Authorization,mode' always; add_header Access-Control-Allow-Methods 'GET,POST,PUT,DELETE,OPTIONS' always; add_header Access-Control-Allow-Credentials 'true' always; return 204; } # 处理非OPTIONS请求 add_header Access-Control-Allow-Origin 'https://main.dyyfxsm3lnw8e.amplifyapp.com,https://xxxxxxx-xi.vercel.app' always; add_header Access-Control-Allow-Headers 'Content-Type,Authorization,mode' always; add_header Access-Control-Allow-Methods 'GET,POST,PUT,DELETE,OPTIONS' always; add_header Access-Control-Allow-Credentials 'true' always; proxy_pass http://ip:8138; # 传递真实请求信息给后端网关 proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header X-Forwarded-Proto $scheme; } listen 443 ssl; # managed by Certbot ssl_certificate /etc/letsencrypt/live/api2.domain.org/fullchain.pem; # managed by Certbot ssl_certificate_key /etc/letsencrypt/live/api2.domain.org/privkey.pem; # managed by Certbot include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot } server { if ($host = api2.domain.org) { return 301 https://$host$request_uri; } # managed by Certbot server_name api2.domain.org; listen 80; return 404; # managed by Certbot }
三、Spring Boot网关的CORS补充配置
为避免多层代理导致的CORS失效,需在网关层面也配置CORS规则:
方式1:通过application.yml配置
spring: cloud: gateway: globalcors: cors-configurations: '[/**]': allowed-origins: "https://main.dyyfxsm3lnw8e.amplifyapp.com,https://xxxxxxx-xi.vercel.app" allowed-methods: "*" allowed-headers: "*" allow-credentials: true
方式2:通过Java配置类
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.cors.CorsConfiguration; import org.springframework.web.cors.reactive.CorsWebFilter; import org.springframework.web.cors.reactive.UrlBasedCorsConfigurationSource; import java.util.Arrays; @Configuration public class CorsConfig { @Bean public CorsWebFilter corsWebFilter() { CorsConfiguration corsConfig = new CorsConfiguration(); corsConfig.setAllowedOrigins(Arrays.asList("https://main.dyyfxsm3lnw8e.amplifyapp.com", "https://xxxxxxx-xi.vercel.app")); corsConfig.setAllowedMethods(Arrays.asList("GET", "POST", "PUT", "DELETE", "OPTIONS")); corsConfig.setAllowedHeaders(Arrays.asList("*")); corsConfig.setAllowCredentials(true); UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource(); source.registerCorsConfiguration("/**", corsConfig); return new CorsWebFilter(source); } }
四、前端请求注意事项
- 确认React应用中Keycloak初始化的
redirectUri配置正确,需指向当前应用的域名,示例:import Keycloak from 'keycloak-js'; const keycloak = new Keycloak({ url: 'https://ip/realms/admin_console_realm', realm: 'admin_console_realm', clientId: 'admin_console_client', redirectUri: window.location.origin + '/' }); - 若
mode头是前端误添加的自定义头,可直接移除,减少配置复杂度
内容的提问来源于stack exchange,提问作者Peter Penzov
相关产品推荐
相关产品推荐

