簡介
在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();
}
請註意,根據實際需求,你可能還需要更精細地控制哪些路由應該禁用重定向行為。