面试官:业务开发时,接口不能对外暴露怎么办?我有 3 种实现方案!


来源:blog.csdn.net/m0_71777195
/article/details/127243452

  • 1. 内外网接口微服务隔离
  • 2. 网关 + redis 实现白名单机制
  • 3. 方案三 网关 + AOP
  • 具体实操

在业务开发的时候,经常会遇到某一个接口不能对外暴露,只能内网服务间调用的实际需求。面对这样的情况,我们该如何实现呢?今天,我们就来理一理这个问题,从几个可行的方案中,挑选一个来实现。

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

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

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

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

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

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

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

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

3. 方案三 网关 + AOP

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

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

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

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

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

具体实操

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

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

@Component
public class AuthFilter implements GlobalFilterOrdered {
    @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 "该接口只允许内部服务调用";
}

程序汪接私活项目目录,2023年总结

Java项目分享  最新整理全集,找项目不累啦 07版

程序汪10万接的无线共享充电宝项目,开发周期3个月

程序汪1万接的企业官网项目,开发周期15天

程序汪8万接的共享口罩项目,开发周期1个月

程序汪8万块的饮水机物联网私活项目经验分享

程序汪接的4万智慧餐饮项目

程序汪接的酒店在线开房项目,另外一个好听的名字叫智慧酒店


欢迎添加程序汪个人微信 itwang008  进粉丝群或围观朋友圈


相关推荐

  • Java之父宣布退休!
  • 英雄联盟的“翻译官”卖了200多亿
  • 上岸南大,面临抉择!
  • DeepMind 发布 JEST 算法,AI 模型训练耗能降低十倍
  • 1个芯片顶英伟达3个?这个偏爱印度的创始人爆肝8年,终于等来抢英伟达泼天富贵的一天!
  • 都说 RAG “烂大街”了,但为何深度应用寥寥无几?| 直播预告
  • 《中国开发者画像洞察研究报告 2024》报告发布:鸿蒙生态存在百万级人才缺口,潜在新就业岗位超过300万个
  • “我的代码被微软和 OpenAI 抄了,维权后被他们耗了两年”
  • LeCun新作:神经网络在实践中的灵活性到底有多大?
  • 语义熵识破LLM幻觉!牛津大学新研究登Nature
  • 全球首个芯片设计开源大模型诞生!5年重塑5000亿美元半导体行业
  • 全球247亿美元豪赌GenAI,疯狂入局AI成高风险博弈?
  • OpenAI「突拔网线」,国内大厂笑疯!泼天流量来了,微软急伸橄榄枝
  • ACL 2024 | OceanGPT(沧渊):面向海洋科学任务的大型语言模型初探
  • 什么是大模型所需要的知识?人大提出DPA-RAG高效对齐检索器与大模型偏好
  • 快速“水”论文必备:82个即插即用涨点模块!
  • 海外LLM高质量数据集免费送
  • AI时代:企业如何抓住人工智能的黄金机遇?
  • Apache SeaTunnel——OLAP 引擎的数据动脉
  • 数据中心疯狂扩张!谷歌的温室气体排放量在五年内激增48%