SpringCloud gateway跨域配置的操作

gateway跨域配置

gateway允许跨域的配置和zuul的不一样,记录一下。

版本

 <parent>        <groupId>org.springframework.boot</groupId>        <artifactId>spring-boot-starter-parent</artifactId>        <version>2.0.6.RELEASE</version>        <relativePath/> <!-- lookup parent from repository -->    </parent>     <properties>        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>        <java.version>1.8</java.version>        <spring-cloud.version>Finchley.SR1</spring-cloud.version>    </properties>
import org.springframework.cloud.client.discovery.DiscoveryClient;import org.springframework.cloud.gateway.discovery.DiscoveryClientRouteDefinitionLocator;import org.springframework.cloud.gateway.discovery.DiscoveryLocatorProperties;import org.springframework.cloud.gateway.route.RouteDefinitionLocator;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.http.HttpHeaders;import org.springframework.http.HttpMethod;import org.springframework.http.HttpStatus;import org.springframework.http.codec.ServerCodecConfigurer;import org.springframework.http.codec.support.DefaultServerCodecConfigurer;import org.springframework.http.server.reactive.ServerHttpRequest;import org.springframework.http.server.reactive.ServerHttpResponse;import org.springframework.web.cors.reactive.CorsUtils;import org.springframework.web.server.ServerWebExchange;import org.springframework.web.server.WebFilter;import org.springframework.web.server.WebFilterChain;import reactor.core.publisher.Mono; /** * 跨域允许 */@Configurationpublic class CorsConfig {    private static final String MAX_AGE = "18000L";     @Bean    public WebFilter corsFilter() {        return (ServerWebExchange ctx, WebFilterChain chain) -> {            ServerHttpRequest request = ctx.getRequest();            if (CorsUtils.isCorsRequest(request)) {                HttpHeaders requestHeaders = request.getHeaders();                ServerHttpResponse response = ctx.getResponse();                HttpMethod requestMethod = requestHeaders.getAccessControlRequestMethod();                HttpHeaders headers = response.getHeaders();                headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, requestHeaders.getOrigin());                headers.addAll(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, requestHeaders                        .getAccessControlRequestHeaders());                if(requestMethod != null){                    headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS, requestMethod.name());                }                headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");                headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS, "*");                headers.add(HttpHeaders.ACCESS_CONTROL_MAX_AGE, MAX_AGE);                if (request.getMethod() == HttpMethod.OPTIONS) {                    response.setStatusCode(HttpStatus.OK);                    return Mono.empty();                }             }            return chain.filter(ctx);        };    }     @Bean    public ServerCodecConfigurer serverCodecConfigurer() {        return new DefaultServerCodecConfigurer();    }     /**     * 如果使用了注册中心(如:Eureka),进行控制则需要增加如下配置     */    @Bean    public RouteDefinitionLocator discoveryClientRouteDefinitionLocator(DiscoveryClient discoveryClient,                                                                        DiscoveryLocatorProperties properties) {        return new DiscoveryClientRouteDefinitionLocator(discoveryClient, properties);    }}

gateway解决前端跨域问题

前后端分离普遍都会遇到跨域问题,项目内用到了网关模块,所以我们可以在网关中解决。

解决

增加以下两个类既可

package com.him.gateway.config;import com.him.gateway.filter.CorsResponseHeaderFilter;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;/** * 配置跨域问题 * * @author liaoyuxing * @date 2021-5-20 */@Configurationpublic class CorsConfig {    @Bean    public CorsResponseHeaderFilter corsResponseHeaderFilter() {        return new CorsResponseHeaderFilter();    }    @Bean    public CorsWebFilter corsWebFilter() {        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();        CorsConfiguration corsConfiguration = new CorsConfiguration();        corsConfiguration.addAllowedHeader("*");        corsConfiguration.addAllowedMethod("*");        corsConfiguration.addAllowedOrigin("*");        corsConfiguration.setAllowCredentials(true);        corsConfiguration.setMaxAge(600L);        source.registerCorsConfiguration("/**", corsConfiguration);        return new CorsWebFilter(source);    }}
package com.him.gateway.filter;import org.springframework.cloud.gateway.filter.GatewayFilterChain;import org.springframework.cloud.gateway.filter.GlobalFilter;import org.springframework.cloud.gateway.filter.NettyWriteResponseFilter;import org.springframework.core.Ordered;import org.springframework.http.HttpHeaders;import org.springframework.web.server.ServerWebExchange;import reactor.core.publisher.Mono;import java.util.ArrayList;/** * 跨域请求头重复处理过滤器 * * @author liaoyuxing * @date 2021-5-20 */public class CorsResponseHeaderFilter implements GlobalFilter, Ordered {    @Override    public int getOrder() {        // 指定此过滤器位于NettyWriteResponseFilter之后        // 即待处理完响应体后接着处理响应头        return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER + 1;    }    @Override    @SuppressWarnings("serial")    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {        return chain.filter(exchange).then(Mono.defer(() -> {            exchange.getResponse().getHeaders().entrySet().stream()                    .filter(kv -> (kv.getValue() != null && kv.getValue().size() > 1))                    .filter(kv -> (kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN)                            || kv.getKey().equals(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS)))                    .forEach(kv ->                    {                        kv.setValue(new ArrayList<String>() {{                            add(kv.getValue().get(0));                        }});                    });            return chain.filter(exchange);        }));    }}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

用最多的梦面对未来

SpringCloud gateway跨域配置的操作

相关文章:

你感兴趣的文章:

标签云: