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)
)
伴随而来的是另外的问题,文件上传相关接口就会出问题。
问题
会出现接口访问不稳定的情况,有时候会特别慢。