解决网关跨域问题

 配置类:

/**
 * 网关配置类
 *
 * @author lyf
 * @date 2022/01/01 00:00 周六
 **/
@Configuration(proxyBeanMethods = false)
public class GatewayConfig {

    /**
     * context-path
     */
    @Value("${server.servlet.context-path:fast-common-gateway}")
    private String prefix;

    /**
     * 过滤server.servlet.context-path属性配置的项目路径,防止对后续路由策略产生影响,因为gateway网关不支持servlet
     *
     * @return
     */
    @Bean
    public WebFilter apiPrefixFilter() {
        return (exchange, chain) ->
        {
            ServerHttpRequest request = exchange.getRequest();
            String path = request.getURI().getRawPath();
            path = path.startsWith(prefix) ? path.replaceFirst(prefix, "") : path;
            ServerHttpRequest newRequest = request.mutate().path(path).build();
            return chain.filter(exchange.mutate().request(newRequest).build());
        };
    }

    /**
     * 跨域配置
     *
     * @return
     */
    @Bean
    public CorsWebFilter corsFilter() {
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(false);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        source.registerCorsConfiguration("/**", config);
        return new CorsWebFilter(source);
    }

    @Bean
    public GlobalExceptionHandler globalExceptionHandler() {
        return new GlobalExceptionHandler();
    }

}

过滤器(关键):

/**
 * 自定义全局过滤器类
 *
 * @author lyf
 * @date 2022/01/01 00:00 周六
 **/
@Slf4j
@Component
public class AccessLogGlobalFilter implements GlobalFilter, Filter {

    private static final String START_TIME = "startTime";

    private static final String X_REAL_IP = "X-Real-IP";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        exchange.getAttributes().put(START_TIME, System.currentTimeMillis());

        return chain
                // 继续调用filter
                .filter(exchange)
                // filter的后置处理
                .then(
                        Mono.fromRunnable(
                                () -> {
                                    Long startTime = exchange.getAttribute(START_TIME);
                                    if (startTime != null) {
                                        Long executeTime = (System.currentTimeMillis() - startTime);

                                        // 解决网关转发到微服务时的跨域问题
                                        exchange.getResponse().getHeaders().entrySet().stream()
                                                .filter(entry -> (entry.getValue() != null && entry.getValue().size() > 1))
                                                .filter(entry -> HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN.equals(entry.getKey()) || HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS.equals(entry.getKey()))
                                                .forEach(entry -> {
                                                    entry.setValue(Collections.singletonList(entry.getValue().get(1)));
                                                });

                                        // 调试模式下输出访问日志
                                        List<String> ips = exchange.getRequest().getHeaders().get(X_REAL_IP);
                                        String ip = ips != null ? ips.get(0) : null;
                                        String host = exchange.getRequest().getURI().getHost();
                                        String method = exchange.getRequest().getMethod().name();
                                        String path = exchange.getRequest().getURI().getRawPath();
                                        MultiValueMap<String, String> queryParams = exchange.getRequest().getQueryParams();
                                        int code = exchange.getResponse().getStatusCode() == null ? 500 : exchange.getResponse().getStatusCode().value();
                                        log.debug("IP:[{}],Host:[{}],Method:[{}],Path:[{}],QueryParams:{},StatusCode:{},Time:{}ms"
                                                , ip, host, method, path, queryParams, code, executeTime);
                                        log.debug("==================================================================================================================");
                                    }
                                }
                        )
                );
    }

    /**
     * 解决网关转发到微服务时的跨域问题
     *
     * @param servletRequest
     * @param servletResponse
     * @param filterChain
     */
    @SneakyThrows
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) {
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        HttpServletRequest request = (HttpServletRequest) servletRequest;

        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "*");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "*");

        String method = request.getMethod();
        if (SaHttpMethod.OPTIONS.name().equalsIgnoreCase(method)) {
            servletResponse.getOutputStream().write("Success".getBytes(StandardCharsets.UTF_8));
        } else {
            filterChain.doFilter(servletRequest, servletResponse);
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

风流倜傥唐伯虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值