happycuiqq 2018-12-24 16:57 采纳率: 50%
浏览 8245

SpringCloud GateWay 自定义GatewayFilterFactory时如何读取body体中内容?

1.需求

需要在gateway网关层,进行参数的签名校验。
前提: 所有的请求都是以post请求,参数都在body体中。

2.思路

在网关层增加自定义的过滤器,对body体中的签名是否合法进行校验

3.具体代码实现

gateway采用了webflux的方式。
对webflux不熟悉。
从网上找到的解决方案,先从webflux中获取body,再填入request中进行传递。

代码如下:


public class SignFilter implements GatewayFilter, Ordered {
//获取requestBody
  String requestBody = getRequstBody(serverRequest);

                //各种业务逻辑

                  //最后封装request,传给下一级
        LoggerUtil.logger().info("signfilter校验成功,路由转发");
        return chain.filter(exchange.mutate().request(getRequest(serverHttpRequest, requestBody)).build());
                }

                /**
     * 获取requestBody
     * 这个方法可能需要优化
     *
     * @param serverRequest
     * @return
     */
    private String getRequstBody(ServerRequest serverRequest) {
        StringBuilder stringBuilder = new StringBuilder();
        serverRequest.bodyToMono(String.class).subscribe(s -> {
            stringBuilder.append(s);
        });
        return stringBuilder.toString();
    }

    /**
     * 重新封装reqeust
     *
     * @param serverHttpRequest
     * @param requestBody
     * @return
     */
    private ServerHttpRequest getRequest(ServerHttpRequest serverHttpRequest, String requestBody) {
        //下面的将请求体再次封装写回到request里,传到下一级,否则,由于请求体已被消费,后续的服务将取不到值
        URI uri = serverHttpRequest.getURI();
        ServerHttpRequest request = serverHttpRequest.mutate().uri(uri).build();
        DataBuffer bodyDataBuffer = stringToDataBuffer(requestBody);
        Flux<DataBuffer> bodyFlux = Flux.just(bodyDataBuffer);

        request = new ServerHttpRequestDecorator(request) {
            @Override
            public Flux<DataBuffer> getBody() {
                return bodyFlux;
            }
        };
        return request;
    }

}

3.2 还有一个方案是

readBody方案

 .route("read_body_pred", r -> r.host("*.readbody.org")
                        .and().readBody(String.class,
                                        s -> s.trim().equalsIgnoreCase("hi"))
                    .filters(f -> f.prefixPath("/httpbin")
                            .addResponseHeader("X-TestHeader", "read_body_pred")
                    ).uri(uri)
                )

伴随而来的是另外的问题,文件上传相关接口就会出问题。

问题

会出现接口访问不稳定的情况,有时候会特别慢。

希望解决的问题

1.好的网关层校验的思路提供一下

2.提供一种 新的在filter中读取body的方案

3.如果只能采用这种读取body的方案,是否遇到过接口不稳定的情况

  • 写回答

1条回答 默认 最新

  • for_bf 2020-04-30 12:39
    关注

    不稳定原因在于readBody方法是异步的,可能filters还没生效就到controller层了

    评论

报告相同问题?

悬赏问题

  • ¥50 切换TabTip键盘的输入法
  • ¥15 可否在不同线程中调用封装数据库操作的类
  • ¥15 微带串馈天线阵列每个阵元宽度计算
  • ¥15 keil的map文件中Image component sizes各项意思
  • ¥20 求个正点原子stm32f407开发版的贪吃蛇游戏
  • ¥15 划分vlan后,链路不通了?
  • ¥20 求各位懂行的人,注册表能不能看到usb使用得具体信息,干了什么,传输了什么数据
  • ¥15 Vue3 大型图片数据拖动排序
  • ¥15 Centos / PETGEM
  • ¥15 划分vlan后不通了