1.内外网接口微服务隔离
2.网关redis实现白名单机制。
3.选项3网关AOP
具体实践
在业务开发中,我们经常会遇到一个接口不能对外公开,只能在内网服务之间调用的实际需求。面对这样的情况,如何才能实现?今天我们就来看看这个问题,从几个可行的方案中选择一个来实现。
1.内外网接口微服务隔离
将对外公开的接口和对内公开的接口分别放在两个微服务上。一个服务中的所有接口都对外公开,另一个服务的接口只能在intranet服务之间调用。
在这个方案中,需要额外编写一个只对内部公开接口的微服务,将所有只能对内部公开的业务接口聚合到这个微服务中。通过这个聚合的微服务,可以分别从各个业务端获取资源。
在这个方案中,增加了一个转发请求的微服务,增加了系统的复杂度、调用的耗时和后期的维护成本。
基于Spring Boot My Batis Plus Vue元素的后台管理系统的用户小程序支持RBAC动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。
项目地址:https://gitee.com/zhijiantianya/ruoyi-vue-pro.
文章教程:https://doc.iocoder.cn/video/
2.网关redis实现白名单机制。
在redis中维护一个windows套接字白名单。当外部请求到达网关时,从redis获取接口白名单,让白名单中的接口通过,否则拒绝。
这种方案的优点是不侵入业务代码,只需要维护白名单;
缺点是白名单的维护是一个持续性的工作。很多公司业务拓展不能直接接触redis,只能申请工单,增加了开发成本。另外,每次有请求进来,都需要判断白名单,增加了系统响应的耗时。考虑到正常情况下大部分外部传入请求都在白名单中,只有少数恶意请求会被白名单机制拦截,因此该方案性价比很低。
基于春云阿里巴巴网关Nacos Rocket MQ Vue元素的后台管理系统用户小程序,支持RBAC动态权限、多租户、数据权限、工作流、三方登录、支付、短信、商城等功能。
项目地址:https://gitee.com/zhijiantianya/yudao-cloud.
文章教程:https://doc.iocoder.cn/video/
3.选项3网关AOP
与第二种方案中接口的白名单判断相比,第三种方案是判断请求的来源,并将这个判断下沉到服务端。避免了网关侧的逻辑判断,从而提高了系统的响应速度。
我们知道,外部传入的请求会通过网关分发到具体的业务端,内部服务之间的调用不需要经过外部网关(k8s服务)。
根据这个特性,我们可以在所有通过网关的请求的头部添加一个字段。业务接口收到请求后,会判断该字段是否在表头。如果是,说明请求来自外部,如果不是,则属于内部服务的调用,然后根据接口是否属于内部接口来决定是否释放请求。
该方案将内外网的访问权限分配给所有业务方,消除了网关处理的系统性瓶颈。同时,开发人员可以在业务端直接确定接口的内外网访问权限,提高了开发效率,增加了代码的可读性。
当然,这种方案会对业务代码造成干扰,但可以通过注释最小化。
具体实践
下面是方案3的具体代码演示。
首先,在网关端,您需要在传入的请求头中添加一个外部网络标识符:from=public。
@ ComponentpublicclassAuthFilterimplementsGlobalFilter,Ordered { @ overridepubonfilter(ServerWebExchangeexchange,GatewayFilterChainchain){ return chain。过滤器(交换。变异().request(exchange.getRequest().变异()。标头(' id '' ').标题('从''公共').build()).build());} @ OverridepublicintgetOrder(){ return 0;}}
接着,编写内外网访问权限判断的面向切面编程和注解
@ Aspect @ Component @ SLF 4 jpublicasonlynetaccessaspect { @ Pointcut(' @ within(org。打开mmlab。站台。常见。注释。onlynetaccessenclass(){ })publicodionlynetaccessenclass(){ } @ Before(value=' onlynetaccessenced()| | onlynetaccessenclass()')public vid Before(){ http servlet requestsr=。get request();字符串来自=HSR。获取标题(“from”);如果(!StringUtils.isEmpty(来自“公共”).等于(来自)){ log。错误(' thisapiisonyallowedinvokedbyintresource ');thrownewMMException(ReturnEnum .c _网络_互联网_访问_不允许_错误);} } } @目标({ElementType .方法})@Retention(RetentionPolicy .运行时)@ documented public @ interfaceOnlyIntranetAccess { }
最后,在只能内网访问的接口上加上@OnlyIntranetAccess注解即可
@ get mapping('/role/add ')@ onlynetaccesspublicstringonlyintranetaccess(){ return '该接口只允许内部服务调用;}
审核彭静
标签:接口业务请求