spring cloud gateway如何修改返回response







前言:项目过程中,做数据字段权限,需要在接口返回过程中,动态的抹去一些字段的值。于是我就提出在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;
    }

}





其实只需要这样一个过滤器,就已经可以实现数据权限动态配置动态过滤的效果。

暂无评论