前语

通过一年的尽力,终于上了本年优异作者榜单了,求票求票,每人能够投8票。顶我一波呀,十分感谢。
2022年度人气创作者打榜中,快来帮我打榜吧~ rank./rank/2022/w…

image.png
在实践工作中,咱们需求经常跟第三方渠道打交道,可能会对接第三方渠道API接口,或许提供API接口给第三方渠道调用。

那么问题来了,假如规划一个优雅的API接口,能够满意:安全性、可重复调用、稳定性、好定位问题等多方面需求?

今天跟大家一起聊聊规划API接口时,需求留意的一些当地,期望对你会有所协助。

1. 签名

为了避免API接口中的数据被篡改,很多时分咱们需求对API接口做签名

接口恳求方将恳求参数 + 时刻戳 + 密钥拼接成一个字符串,然后通过md5等hash算法,生成一个前面sign。

然后在恳求参数或许恳求头中,添加sign参数,传递给API接口。

API接口的网关服务,获取到该sign值,然后用相同的恳求参数 + 时刻戳 + 密钥拼接成一个字符串,用相同的m5算法生成别的一个sign,对比两个sign值是否持平。

假如两个sign持平,则认为是有用恳求,API接口的网关服务会将给恳求转发给相应的事务体系。

假如两个sign不持平,则API接口的网关服务会直接回来签名过错。

问题来了:签名中为什么要加时刻戳?

答:为了安全性考虑,避免同一次恳求被反复运用,添加了密钥没破解的可能性,咱们有必要要对每次恳求都设置一个合理的过期时刻,比方:15分钟。

这样一次恳求,在15分钟之内是有用的,超越15分钟,API接口的网关服务会回来超越有用期的反常提示。

目前生成签名中的密钥有两种方法:

一种是两边约好一个固定值privateKey。

另一种是API接口提供方给出AK/SK两个值,两边约好用SK作为签名中的密钥。AK接口调用方作为header中的accessKey传递给API接口提供方,这样API接口提供方能够依据AK获取到SK,而生成新的sgin。

2. 加密

有些时分,咱们的API接口直接传递的十分重要的数据,比方:用户的银行卡号、转账金额、用户身份证等,假如将这些参数,直接明文,暴露到公网上是十分危险的工作。

由此,咱们需求对数据进行加密

目前运用比较多的是用BASE64加解密。

咱们能够将一切的数据,装置必定的规则拼接成一个大的字符串,然后在加一个密钥,拼接到一起。

然后运用JDK1.8之后的Base64东西类处理,作用如下:

【加密前的数据】www.baidu.com
【加密后的数据】d3d3LmJhaWR1LmNvbQ==

为了安全性,运用Base64能够加密多次。

API接口的调用方在传递参数时,body中只要一个参数data,它便是base64之后的加密数据。

API接口的网关服务,在接收到data数据后,依据两边事前预订的密钥、加密算法、加密次数等,进行解密,而且反序列化出参数数据。

3. ip白名单

为了进一步加强API接口的安全性,避免接口的签名或许加密被破解了,攻击者能够在自己的服务器上恳求该接口。

需求约束恳求ip,添加ip白名单

只要在白名单中的ip地址,才能成功恳求API接口,不然直接回来无拜访权限。

ip白名单也能够加在API网关服务上。

但也要避免公司的内部应用服务器被攻破,这种状况也能够从内部服务器上发起API接口的恳求。

这时分就需求添加web防火墙了,比方:ModSecurity等。

4. 限流

假如你的API接口被第三方渠道调用了,这就意味着着,调用频率是没法控制的。

第三方渠道调用你的API接口时,假如并发量一下子太高,可能会导致你的API服务不可用,接口直接挂掉。

由此,有必要要对API接口做限流

限流方法有三种:

  1. 对恳求ip做限流:比方同一个ip,在一分钟内,对API接口总的恳求次数,不能超越10000次。
  2. 对恳求接口做限流:比方同一个ip,在一分钟内,对指定的API接口,恳求次数不能超越2000次。
  3. 对恳求用户做限流:比方同一个AK/SK用户,在一分钟内,对API接口总的恳求次数,不能超越10000次。

咱们在实践工作中,能够通过nginxredis或许gateway完成限流的功能。

5. 参数校验

咱们需求对API接口做参数校验,比方:校验必填字段是否为空,校验字段类型,校验字段长度,校验枚举值等等。

这样做能够阻拦一些无效的恳求。

比方在新增数据时,字段长度超越了数据字段的最大长度,数据库会直接报错。

但这种反常的恳求,咱们完全能够在API接口的前期进行辨认,没有必要走到数据库保存数据那一步,糟蹋体系资源。

有些金额字段,本来是正数,但假如用户传入了负数,万一接口没做校验,可能会导致一些没必要的丢失。

还有些状态字段,假如不做校验,用户假如传入了体系中不存在的枚举值,就会导致保存的数据反常。

由此可见,做参数校验是十分有必要的。

在Java中校验数据运用最多的是hiberateValidator框架,它里边包含了@Null、@NotEmpty、@Size、@Max、@Min等注解。

用它们校验数据十分方便。

当然有些日期字段和枚举字段,可能需求通过自界说注解的方法完成参数校验。

6. 一致回来值

我之前调用过他人的API接口,正常回来数据是一种json格局,比方:

{
    "code":0,
    "message":null,
    "data":[{"id":123,"name":"abc"}]
},

签名过错回来的json格局:

{
    "code":1001,
    "message":"签名过错",
    "data":null
}

没有数据权限回来的json格局:

{
    "rt":10,
    "errorMgt":"没有权限",
    "result":null
}

这种是比较坑的做法,回来值中有多种不同格局的回来数据,这样会导致对接方很难了解。

呈现这种状况,可能是API网关界说了一向回来值结构,事务体系界说了别的一种回来值结构。假如是网关反常,则回来网关界说的回来值结构,假如是事务体系反常,则回来事务体系的回来值结构。

但这样会导致API接口呈现不同的反常时,回来不同的回来值结构,十分不利于接口的保护。

其实这个问题咱们能够在规划API网关时处理。

事务体系在呈现反常时,抛出事务反常的RuntimeException,其中有个message字段界说反常信息。

一切的API接口都有必要通过API网关,API网关捕获该事务反常,然后转换成一致的反常结构回来,这样能一致回来值结构。

7. 一致封装反常

咱们的API接口需求对反常进行一致处理。

不知道你有没有遇到过这种场景:有时分在API接口中,需求拜访数据库,但表不存在,或许sql句子反常,就会直接把sql信息在API接口中直接回来。

回来值中包含了反常堆栈信息数据库信息过错代码和行数等信息。

假如直接把这些内容暴露给第三方渠道,是很危险的工作。

有些不法分子,运用接口回来值中的这些信息,有可能会进行sql注入或许直接脱库,而对咱们体系形成必定的丢失。

因此十分有必要对API接口中的反常做一致处理,把反常转换成这样:

{
    "code":500,
    "message":"服务器内部过错",
    "data":null
}

回来码code500,回来信息message服务器内部反常

这样第三方渠道就知道是API接口呈现了内部问题,但不知道详细原因,他们能够找咱们排查问题。

咱们能够在内部的日志文件中,把堆栈信息、数据库信息、过错代码行数等信息,打印出来。

咱们能够在gateway中对反常进行阻拦,做一致封装,然后给第三方渠道的是处理后没有敏感信息的过错信息。

8. 恳求日志

在第三方渠道恳求你的API接口时,接口的恳求日志十分重要,通过它能够快速的分析和定位问题。

咱们需求把API接口的恳求url、恳求参数、恳求头、恳求方法、响应数据和响应时刻等,记载到日志文件中。

最好有traceId,能够通过它串联整个恳求的日志,过滤多余的日志。

当然有些时分,恳求日志不光是你们公司开发人员需求检查,第三方渠道的用户也需求能检查接口的恳求日志。

这时就需求把日志落地到数据库,比方:mongodb或许elastic search,然后做一个UI页面,给第三方渠道的用户注册检查权限。这样他们就能在外网检查恳求日志了,他们自己也能定位一部分问题。

9. 幂等规划

第三方渠道极有可能在极短的时刻内,恳求咱们接口多次,比方:在1秒内恳求两次。有可能是他们事务体系有bug,或许在做接口调用失利重试,因此咱们的API接口需求做幂等规划

也便是说要支撑在极短的时刻内,第三方渠道用相同的参数恳求API接口多次,第一次恳求数据库会新增数据,但第2次恳求今后就不会新增数据,但也会回来成功。

这样做的目的是不会发生过错数据。

咱们在日常工作中,能够通过在数据库中添加唯一索引,或许在redis保存requestId和恳求参来确保接口幂等性。

对接口幂等性感兴趣的小伙伴,能够看看我的另一篇文章《高并发下怎么确保接口的幂等性?》,里边有十分详细的介绍。

10. 约束记载条数

关于对我提供的批量接口,必定要约束恳求的记载条数

假如恳求的数据太多,很简单形成API接口超时等问题,让API接口变得不稳定。

通常状况下,主张一次恳求中的参数,最多支撑传入500条记载。

假如用户传入多余500条记载,则接口直接给出提示。

主张这个参数做成可装备的,而且要事前跟第三方渠道协商好,避免上线后发生不必要的问题。

11. 压测

上线前咱们必须要对API接口做一下压力测验,知道各个接口的qps状况。

以便于咱们能够更好的预估,需求布置多少服务器节点,关于API接口的稳定性至关重要。

之前虽说对API接口做了限流,但是实践上API接口是否能够到达约束的阀值,这是一个问号,假如不做压力测验,是有很大危险的。

比方:你API接口限流1秒只允许50次恳求,但实践API接口只能处理30次恳求,这样你的API接口也会处理不过来。

咱们在工作中能够用jmeter或许apache benc对API接口做压力测验。

12. 异步处理

一般的API接口的逻辑都是同步处理的,恳求完之后立刻回来结果。

但有时分,咱们的API接口里边的事务逻辑十分复杂,特别是有些批量接口,假如同步处理事务,耗时会十分长。

这种状况下,为了提升API接口的性能,咱们能够改成异步处理

在API接口中能够发送一条mq音讯,然后直接回来成功。之后,有个专门的mq顾客去异步消费该音讯,做事务逻辑处理。

直接异步处理的接口,第三方渠道有两种方法获取到。

第一种方法是:咱们回调第三方渠道的接口,奉告他们API接口的处理结果,很多付出接口便是这么玩的。

第二种方法是:第三方渠道通过轮询调用咱们别的一个查询状态的API接口,每隔一段时刻查询一次状态,传入的参数是之前的那个API接口中的id集合。

13. 数据脱敏

有时分第三方渠道调用咱们API接口时,获取的数据中有一部分是敏感数据,比方:用户手机号、银行卡号等等。

这样信息假如通过API接口直接保存到外网,是十分不安全的,很简单形成用户隐私数据泄露的问题。

这就需求对部分数据做数据脱敏了。

咱们能够在回来的数据中,部分内容用星号代替。

已用户手机号为例:182****887

这样即使数据被泄露了,也只泄露了一部分,不法分子拿到这份数据也没啥用。

14. 完好的接口文档

说实话,一份完好的API接口文档,在两边做接口对接时,能够削减很多沟通成本,让对方少走很多弯路。

接口文档中需求包含如下信息:

  1. 接口地址
  2. 恳求方法,比方:post或get
  3. 恳求参数和字段介绍
  4. 回来值和字段介绍
  5. 回来码和过错信息
  6. 加密或签名示例
  7. 完好的恳求demo
  8. 额外的说明,比方:注册ip白名单。

接口文档中最好能够一致接口和字段名称的命名风格,比方都用驼峰标识命名。

一致字段的类型和长度,比方:id字段用Long类型,长度规则20。status字段用int类型,长度固定2等。

一致时刻格局字段,比方:time用String类型,格局为:yyyy-MM-dd HH:mm:ss。

接口文档中写明AK/SK和域名,找某某独自提供等。

通过一年的尽力,终于上了本年优异作者榜单了,求票求票,每人能够投8票。顶我一波呀,十分感谢。

image.png

最终说一句(求重视,别白嫖我)

假如这篇文章对您有所协助,或许有所启示的话,帮忙扫描下发二维码重视一下,您的支撑是我坚持写作最大的动力。

求一键三连:点赞、转发、在看。

重视大众号:【苏三说技术】,在大众号中回复:面试、代码神器、开发手册、时刻管理有超赞的粉丝福利,别的回复:加群,能够跟很多BAT大厂的长辈沟通和学习。

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。