网关过滤规则越界了

Blade 未结 2 90
Jalena
Jalena 剑圣 2024-10-21 10:38

一、该问题的重现步骤是什么?

因为业务关系需要使用gateway来引入外部的业务接口(非BladeX),所以想在gateway里面直接增加路由。


但目前 org.springblade.gateway.filter.RequestFilter 类中默认移除了Url的第一级参数,例如:

http://www.baidu.com/a/b?code=xxx

变成了

http://www.baidu.com/b?code=xxx


二、你期待的结果是什么?实际看到的又是什么?

对于这个URL重写规则是不是应该有个范围,例如 /api/xx 的路径包含了api 的才进行重写规则呢?


三、你正在使用的是什么产品,什么版本?在什么操作系统上?

Bladex 4.1.0


2条回答
  • 2024-10-21 10:55

    因为网关第一层会去nacos请求服务名,以服务名为前缀放到接口地址进行调用。而第一层的服务名是不实际存在于controller的,所以需要把它移除。并且用户自定义的服务名各种可能都有,无法做到精准识别,既然是用了blade体系,那第一层就是服务名必须移除。不同场景不同需求,目前我们还是会保持原样。


    如果不满足你们的场景可自定义逻辑,比如加前缀判断。

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        ServerHttpRequest request = exchange.getRequest();
        String rawPath = request.getURI().getRawPath();
    
        // 定义需要跳过的前缀列表
        List<String> skipPrefixes = Arrays.asList("/blade", "/api");
    
        // 检查原始路径是否以指定的前缀开始
        boolean shouldSkip = skipPrefixes.stream().anyMatch(rawPath::startsWith);
    
        // 如果路径以指定前缀开始,则跳过第一个路径段
        String newPath;
        if (shouldSkip) {
            newPath = "/" + Arrays.stream(StringUtils.tokenizeToStringArray(rawPath, "/"))
                                  .skip(1L)
                                  .collect(Collectors.joining("/"));
        } else {
            // 如果不以指定前缀开始,保留原始路径
            newPath = rawPath;
        }
    
        // 创建新的请求对象并更新路径
        ServerHttpRequest newRequest = request.mutate()
                                              .path(newPath)
                                              .build();
    
        // 更新交换的请求对象
        return chain.filter(exchange.mutate().request(newRequest).build());
    }


    0 讨论(0)
  • 2024-10-21 11:35

    了解,那就自己重写它吧!

    0 讨论(0)
提交回复