该项目是基于鱼皮的《API开发平台》项目的需求和架构设计上进行Golang版本开发的。
这篇文章,主要内容是记录在《XAPI项目》的原架构上,为了应对第三方签名认证的设计,而对原架构的调整修改。
目录
- 原设计架构
- 遇到的问题:当【第三方项目】需要验证自己项目的签名认证时,其AK/SK参数应该放在原架构的哪个部分编写?
- 对架构进行修改
-
- 架构变更后说明:
-
- [1. 增加聚合SDK(私有),仅供API后端使用](#1. 增加聚合SDK(私有),仅供API后端使用)
- [2. 修改客户端SDK(公共),可供用户使用](#2. 修改客户端SDK(公共),可供用户使用)
- [3. 原网关部分,需要提到API后端内](#3. 原网关部分,需要提到API后端内)
- [4. 架构上删除API网关(可选)](#4. 架构上删除API网关(可选))
📢 以下观点仅代表个人观点,不一定反映原架构设计的意图,也可能是我对原架构设计目的的理解不足。如果有任何错误或遗漏之处,请随时指出。
原设计架构
这是原设计架构下的调用接口业务的全流程图:
遇到的问题:当【第三方项目】需要验证自己项目的签名认证时,其AK/SK参数应该放在原架构的哪个部分编写?
在该项目设计中,本就有API签名认证(属于API后端项目设计的),所以需要第三方项目来找API后端验证,而项目中为了方便第三方项目的入驻,架设了API网关,统一帮助第三方项目做API签名认证,所以第三方就不需要来找API后端验证了。这里只是满足了入驻到API后端的校验条件。
但是,对于不同的第三方项目,他们都有自己的设计,所以也会存在自己的API签名认证(属于第三方自己设计的)。如果第三方有自己的API签名认证,那么无论是谁(包括API项目)请求他们接口服务的时候,都要按照其要求进行签名制作(AK、SK将来自于第三方项目系统)。
📢 如果说,该项目设计上,是限制入驻的第三方必须对我方请求的接口都不设置他们的API签名认证拦截的话,如果存在这一硬性条件,那后面的就无需看了,也就是该问题本就不存在。
先试着逐个考虑:
在流程中,请求第三方业务的起始点是从客户端SDK内发出的。所以先从这里考虑:
1. 放在【客户端SDK】
客户端SDK的功能:内部集成了所有入驻的第三方接口协议的请求编码。只需要传递所需的参数就能调用对应第三方接口服务。
使用方:所有人 。
因为该SDK是公开的,每个人都可以下载,只不过里面发出的请求URL都是指向API网关的,如果不是API后端的用户,都会被访问拦截,无法使用该服务。也就是说,保护第三方实际业务的方式,是通过隐藏真实的服务请求URL。但其余所需的参数这里都写好了。
这里其实就存在安全隐患了 :
大多第三方服务都有提供接口文档的(比如:Steam、苹果、Google等等),因为公开接口协议本身是很正常的,而要使用其提供的服务,一般都需要使用第三方项目提供的AK、SK,然后根据其设计的签名算法,编写出正确的参数,才能成功访问其服务。
-
如果第三方没有这部分设计,那么只要在网上查找他们真实服务的请求URL,替换掉客户端SDK内的请求地址,就能绕过API网关,直接访问到第三方项目了。
-
如果第三方有这部分设计,那么编写其设计签名部分的代码 ,这里写在客户端SDK内。需要考虑第三方要求的AK、SK如何拿到?但是这里无论使用什么方式拿到AK、SK(比如作为参数传入、或者直接写在客户端SDK内),都是不安全的,因为只要用户拿到AK、SK信息,他就能绕过API网关,直接访问到第三方项目。
结论:不合适
2. 放在【API网关】
API网关的定义 :架构网关时,就对其定义为用于统一的做事情。
这里第三方项目是各不相同的,他们存在自己设计的签名算法,比如有的需要和所有参数一起生成签名,有的需要按照一定的顺序排序后再生成签名,有的拼接参数时需要使用特定的符号,由于这些特殊性,这块是没法抽象出统一的规则来生成签名的。所以需要对每个第三方项目编写特定的代码。这里违背了该API网关的统一做事情的定义。(PS:如果该定义能被打破,那确实可以放在这里,问题得到解决。但是一般项目的核心定义是不应该被改变的。特别这里API网关已经是微服务级别了,其定义更不应该随便修改。)
结论:不合适
对架构进行修改
架构变更后说明:
1. 增加聚合SDK(私有),仅供API后端使用
在原客户端SDK内,实现对接第三方项目的所有协议编码,包含第三方自己的签名算法部分,所需AK、SK参数由调用方传递,也可以写死在该客户端SDK内(只不过写死的话,如果值变更了,需要修改代码重新编译发布)。另外该SDK仅对API后端项目暴露,不再对外暴露。也就是说它其实只是API后端里的代码,只是业务较为独立,可以单领出来方便维护。
2. 修改客户端SDK(公共),可供用户使用
内部包含所有入驻的第三方项目的调用函数,参数是明确个数的、类型确定的,对于调用者来说使用上是非常方便的,无需了解API后端的协议,无需组装json等格式的参数。方便开发者快速接入,该客户端SDK也不与第三方项目直接交互,只是作为与API后端的链接桥梁。而API后端内也不会使用该客户端SDK。
3. 原网关部分,需要提到API后端内
因为客户端SDK直接调用的是API后端的接口,所以API后端就需要有访问控制、权限校验等。
4. 架构上删除API网关(可选)
因为真正访问第三方项目的服务是API后端,而服务端之间的通信可以通过IP验证来保证来源方有效性。
而对于原API网关中的签名校验,因为之前的客户端SDK是直接请求到API网关的,所以需要对来源做校验过滤,而在现在的结构下,客户端SDK是直接请求到API后端的,相关校验过滤已经在API后端内做过了。(或者在API后端前架构一个小网关,让客户端SDK直接请求,然后小网关过滤了之后再转到API后端。不过这样的设计我个人觉得只需要把相关的代码从形式上独立维护即可,不需要真正的作为一个小网关部署)
而对于原API网关中的接口统计,可以放在API后端的主逻辑上,在拿到聚合SDK结果后,统一处理接口统计即可。