spring cloud gateway自定義過濾器,防止後端服務重定向

2024年2月6日 20点热度 0人点赞

簡介

Spring Cloud Gateway作為服務網關的情況下,防止後端服務的重定向行為直接傳遞到客戶端,通常需要在Gateway層面處理響應的3xx狀態碼,特別是針對重定向(如301、302)的情況。可以通過編寫自定義全局過濾器來實現這一目的:

方式一

創建自定義過濾器

創建自定義過濾器DisableBackendRedirectFilter.

package org.fiend.a.gateway.filter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
/**
 * @author Administrator 2024-01-30 17:01:43
 */
public class DisableBackendRedirectGatewayFilter implements GatewayFilter, Ordered {
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            // 檢查響應狀態碼是否為重定向
            int statusCode = exchange.getResponse().getStatusCode().value();
            if (statusCode >= 300 && statusCode < 400) {
                // 如果是重定向,可以修改響應狀態碼和頭部信息,避免客戶端跟隨重定向
                exchange.getResponse().setStatusCode(HttpStatus.OK);
                exchange.getResponse().getHeaders().remove(HttpHeaders.LOCATION);
            }
        }));
    }
    @Override
    public int getOrder() {
        // 設置過濾器執行順序,數值越小優先級越高
        return 0;
    }
}

在上述代碼中,自定義的DisableBackendRedirectFilter會在請求生命周期結束後檢查響應的狀態碼。如果發現是重定向,它會移除Location頭或者將狀態碼改為非重定向狀態,從而阻止客戶端跟隨重定向。

創建自定義過濾器工廠

package org.fiend.a.gateway.config;
import org.fiend.a.gateway.filter.DisableBackendRedirectGatewayFilter;
import org.springframework.cloud.gateway.filter.GatewayFilter;
import org.springframework.cloud.gateway.filter.factory.AbstractGatewayFilterFactory;
import org.springframework.stereotype.Component;
/**
 * @author Administrator 2024-01-30 17:32:02
 */
@Component
public class MyDisableBackendRedirectGatewayFilterFactory extends AbstractGatewayFilterFactory<Object>
{
    @Override
    public GatewayFilter apply(Object config)
    {
        return new DisableBackendRedirectGatewayFilter();
    }
}

配置application.yml

spring:
  cloud:
    gateway:
      routes:
        - id: your_route_id
          # ... route definition details ...
          filters:
            - MyDisableBackendRedirect # 添加剛才的自定義過濾器工廠名字: MyDisableBackendRedirect

方式二

通過編程方式註冊到Spring容器:

@Bean
public RouteLocator customRouteLocator(RouteLocatorBuilder builder) {
    return builder.routes()
        .route("your_route_definition", r -> r.path("/path_to_protect")
            .filters(f -> f.filter(new DisableBackendRedirectFilter()))
            .uri("lb://backend-service"))
        .build();
}

請註意,根據實際需求,你可能還需要更精細地控制哪些路由應該禁用重定向行為。