首页 > 其他分享 >业务开发时,接口不能对外暴露怎么办?

业务开发时,接口不能对外暴露怎么办?

时间:2023-08-18 15:57:52浏览次数:30  
标签:网关 服务 请求 暴露 接口 白名单 怎么办 public

在业务开发的时候,经常会遇到某一个接口不能对外暴露,只能内网服务间调用的实际需求。面对这样的情况,我们该如何实现呢?

今天,我们就来理一理这个问题,从几个可行的方案中,挑选一个来实现。

推荐一个开源免费的 Spring Boot 实战项目:

https://github.com/javastacks/spring-boot-best-practice

1. 内外网接口微服务隔离

将对外暴露的接口和对内暴露的接口分别放到两个微服务上,一个服务里所有的接口均对外暴露,另一个服务的接口只能内网服务间调用。

该方案需要额外编写一个只对内部暴露接口的微服务,将所有只能对内暴露的业务接口聚合到这个微服务里,通过这个聚合的微服务,分别去各个业务侧获取资源。

该方案,新增一个微服务做请求转发,增加了系统的复杂性,增大了调用耗时以及后期的维护成本。

2. 网关 + redis 实现白名单机制

在 redis 里维护一套接口白名单列表,外部请求到达网关时,从 redis 获取接口白名单,在白名单内的接口放行,反之拒绝掉。

该方案的好处是,对业务代码零侵入,只需要维护好白名单列表即可;

不足之处在于,白名单的维护是一个持续性投入的工作,在很多公司,业务开发无法直接触及到 redis,只能提工单申请,增加了开发成本;另外,每次请求进来,都需要判断白名单,增加了系统响应耗时,考虑到正常情况下外部进来的请求大部分都是在白名单内的,只有极少数恶意请求才会被白名单机制所拦截,所以该方案的性价比很低。

3. 方案三 网关 + AOP

相比于方案二对接口进行白名单判断而言,方案三是对请求来源进行判断,并将该判断下沉到业务侧。避免了网关侧的逻辑判断,从而提升系统响应速度。

我们知道,外部进来的请求一定会经过网关再被分发到具体的业务侧,内部服务间的调用是不用走外部网关的(走 k8s 的 service)。

根据这个特点,我们可以对所有经过网关的请求的header里添加一个字段,业务侧接口收到请求后,判断header里是否有该字段,如果有,则说明该请求来自外部,没有,则属于内部服务的调用,再根据该接口是否属于内部接口来决定是否放行该请求。

该方案将内外网访问权限的处理分布到各个业务侧进行,消除了由网关来处理的系统性瓶颈;同时,开发者可以在业务侧直接确定接口的内外网访问权限,提升开发效率的同时,增加了代码的可读性。

当然该方案会对业务代码有一定的侵入性,不过可以通过注解的形式,最大限度的降低这种侵入性。

具体实操

下面就方案三,进行具体的代码演示。

首先在网关侧,需要对进来的请求header添加外网标识符: from=public

@Component
public class AuthFilter implements GlobalFilter, Ordered {
    @Override
    public Mono < Void > filter ( ServerWebExchange exchange, GatewayFilterChain chain ) {
         return chain.filter(
         exchange.mutate().request(
         exchange.getRequest().mutate().header("id", "").header("from", "public").build())
         .build()
         );
    }
 
    @Override
    public int getOrder () {
        return 0;
    }
 }

接着,编写内外网访问权限判断的AOP和注解

@Aspect
@Component
@Slf4j
public class OnlyIntranetAccessAspect {
 @Pointcut ( "@within(org.openmmlab.platform.common.annotation.OnlyIntranetAccess)" )
 public void onlyIntranetAccessOnClass () {}
 @Pointcut ( "@annotation(org.openmmlab.platform.common.annotation.OnlyIntranetAccess)" )
 public void onlyIntranetAccessOnMethed () {
 }
 
 @Before ( value = "onlyIntranetAccessOnMethed() || onlyIntranetAccessOnClass()" )
 public void before () {
     HttpServletRequest hsr = (( ServletRequestAttributes ) RequestContextHolder.getRequestAttributes()) .getRequest ();
     String from = hsr.getHeader ( "from" );
     if ( !StringUtils.isEmpty( from ) && "public".equals ( from )) {
        log.error ( "This api is only allowed invoked by intranet source" );
        throw new MMException ( ReturnEnum.C_NETWORK_INTERNET_ACCESS_NOT_ALLOWED_ERROR);
            }
     }
 }
 
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface OnlyIntranetAccess {
}

最后,在只能内网访问的接口上加上@OnlyIntranetAccess注解即可

@GetMapping ( "/role/add" )
@OnlyIntranetAccess
public String onlyIntranetAccess() {
    return "该接口只允许内部服务调用";
}

你学会了吗?

版权声明:本文为CSDN博主「肥肥技术宅」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。原文链接:https://blog.csdn.net/m0_71777195/article/details/127243452

近期热文推荐:

1.1,000+ 道 Java面试题及答案整理(2022最新版)

2.劲爆!Java 协程要来了。。。

3.Spring Boot 2.x 教程,太全了!

4.别再写满屏的爆爆爆炸类了,试试装饰器模式,这才是优雅的方式!!

5.《Java开发手册(嵩山版)》最新发布,速速下载!

觉得不错,别忘了随手点赞+转发哦!

标签:网关,服务,请求,暴露,接口,白名单,怎么办,public
From: https://www.cnblogs.com/javastack/p/17640707.html

相关文章

  • 文字转语音 - 搭建微软tts整合web服务提供api接口(免费)
     微软tts是业界公认文字转语音效果最佳本文使用docker搭建微软tts服务并提供api接口对外提供服务对接官方免费在线体验接口,搭建后可免费进行调用使用,不保证永久稳定可用调用方式url:http://127.0.0.1:5003/ttsmethod:POST参数 类型 描述text string 语音文字内容voiceName stri......
  • Airtest的iOS实用接口介绍
    1.前言前段时间Airtest更新了1.3.0.1版本,里面涉及非常多的iOS功能新增和改动,今天想详细跟大家聊一下里面的iOS设备接口。PS:本文示例均使用本地连接的iOS设备,Airtest版本为1.3.0.1。2.安装接口:install、install_appAirtest支持通过本地.ipa文件安装APP,也支持通过下载链接安......
  • t113-c-lvgl触摸接口接入
    整合一下最近搞的东西,顺便设计一下ui移植触摸复制port文件到src目录下同时改名字和删除掉不用的东西:/***@filelv_port_indev_templ.c**//*Copythisfileas"lv_port_indev.c"andsetthisvalueto"1"toenablecontent*/#if1/**********************......
  • 2023年第 16期《Python接口自动化+Playwright 》课程,9月10号开学(课程全面升级!)!
    2023年第16期《Python接口自动化+Playwright》课程课程,9月10号开学(课程全面升级!)主讲老师:上海-悠悠上课方式:微信群视频在线教学,方便交流本期上课时间:2023年9月10号-2023年12月3号,晚上20:30-22:30报名费:报名费3000一人(周期3个月)联系微信/QQ:283340479课表如下直播课程主......
  • 使用protobuf生成各大厂的开放平台接口
    protoc-gen-go_api一款用protobuf文件生成go的http调用代码。具体代码见protoc-gen-go_api安装goinstallgithub.com/dev-openapi/protoc-gen-go_api@latest使用依赖googleapis的http.proto和annotations.proto。并且需要放到google/api/目录下如果google/api是在工程文......
  • 常量定义在接口还是类中?
    1.前言最近看项目的时候发现,这个项目把常量定义在接口当中,感觉到很神奇,随之我就想到了一个问题,竟然常量可以定义到接口里,也可以定义到类和枚举中,哪到底哪个更合适一点,于是我上网查了一些资料。得出一下结论2.解析publicinterfaceConstants{intUSER_EROOR=1;int......
  • 记一次奇葩接口
    1.回传接口要求第一次遇到这么奇葩的API接口回传要求:HTTPStatus为500、1000、或者超时、响应慢都要重试前10分钟每30s重试一次。后续每5分钟重试一次。如果12小时还未成功直接丢弃数据你说数据重要嘛,你后面又不要了,说不重要嘛12h的重试。。。所以避免折腾,所有丢弃的数据还......
  • Feign接口返回值加多层泛型,但没有反序列化彻底
    1、问题描述接口返回值加多层泛型,但没有反序列化彻底2、问题原因jackson-databindjar包版本的问题我们之前用的是2.11.2,这个版本有bug,版本变成2.11.3就好了......
  • 关于API数据接口获取商品的数据的说明
    获取商品数据已经成为许多应用程序的重要组成部分。为了实现这一目标,许多公司和技术开发者使用API数据接口来获取相关数据。本文将详细介绍如何使用API数据接口获取商品数据,并使用Python作为编程语言示例来展示相关代码。API数据接口是一种通信协议,它允许不同的应用程序或服务之间......
  • 接口返回图片使用什么类型_JavaWeb
    publicResponseEntity<byte[]>icon(){//第三方接口返回的图片验证码ResponseEntity<byte[]>response=restTemplate.getForEntity(url,byte[].class);……//由后端转发此请求,是因为此处需要做一些特殊处理......