前言:项目过程中,做数据字段权限,需要在接口返回过程中,动态的抹去一些字段的值。于是我就提出在api网关中,动态获取用户角色接口字段权限,来控制是否抹去response中data的值。
1,众所周知,gateway是基于一些列的过滤器及请求转发,来实现api请求聚合,鉴权,限流等功能的,那么修改response同样只需要在全局过滤器中,将reponse中的datajson数据进行修改。
实现过程:
1,定义过滤器
@Configuration
public class ResponseGlobalFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange,
GatewayFilterChain chain) {
//业务代码,调用接口获取当前认证对象的当前接口的字段权限有那些
/****
*
*
**/
//构建响应拦截处理器
BodyHandlerFunction bodyHandler = (resp, body) -> Flux.from(body)
.map(dataBuffer -> {
//响应信息转换为字符串
String reqBody = null;
try {
//dataBuffer 转换为String
reqBody = IOUtils
.inputStreamAsString(dataBuffer.asInputStream(), "UTF-8")
.replaceAll(">\\s{1,}<", "><");
System.out.println(reqBody);
} catch (IOException e) {
e.printStackTrace();
}
return reqBody;
})
.flatMap(orgBody -> {
String rbody = orgBody + "";
/**
*
* 遍历上面获得的当前接口中的字段属性,for循环 使用字符串匹配处理body中 字段属性的值
*
**/
HttpHeaders headers = resp.getHeaders();
if(headers.get("Access-Control-Allow-Origin")!=null && headers.get("Access-Control-Allow-Origin").size()>1){
String value=headers.get("Access-Control-Allow-Origin").get(0);
headers.remove("Access-Control-Allow-Origin");
headers.setAccessControlAllowOrigin(value);
}
if(headers.get("Access-Control-Allow-Credentials")!=null && headers.get("Access-Control-Allow-Credentials").size()>1){
String value=headers.get("Access-Control-Allow-Credentials").get(0);
headers.remove("Access-Control-Allow-Credentials");
headers.setAccessControlAllowCredentials(value=="true");
}
return resp.writeWith(Flux.just(rbody)
.map(bx -> resp.bufferFactory()
.wrap(bx.getBytes())));
}).then();
//构建响应包装类
BodyHandlerServerHttpResponseDecorator responseDecorator = new BodyHandlerServerHttpResponseDecorator(
bodyHandler, exchange.getResponse());
return chain
.filter(exchange.mutate().response(responseDecorator).build());
}
@Override
public int getOrder() {
return NettyWriteResponseFilter.WRITE_RESPONSE_FILTER_ORDER - 1;
}
}
其实只需要这样一个过滤器,就已经可以实现数据权限动态配置动态过滤的效果。