在日常开发中,总会接触到各种接口。前后端数据传输接口,第三方业务平台接口。一个平台的前后端数据传输接口个别都会在内网环境下通信,而且会应用平安框架,所以安全性能够失去很好的爱护。这篇文章重点讨论一下提供给第三方平台的业务接口该当如何设计?咱们应该思考哪些问题?
次要从以上三个方面来设计一个平安的API接口。
一 安全性问题
安全性问题是一个接口必须要保障的标准。如果接口保障不了安全性,那么你的接口相当于间接裸露在公网环境中任人践踏。
1.1 调用接口的先决条件-token
获取token个别会波及到几个参数appid
,appkey
,timestamp
,nonce
,sign
。咱们通过以上几个参数来获取调用零碎的凭证。
appid
和appkey
能够间接通过平台线上申请,也能够线下间接颁发。appid
是全局惟一的,每个appid
将对应一个客户,appkey
须要高度窃密。
timestamp
是工夫戳,应用零碎以后的unix工夫戳。工夫戳的目标就是为了加重DOS攻打。避免申请被拦挡后始终尝试申请接口。服务器端设置工夫戳阀值,如果申请工夫戳和服务器工夫超过阀值,则响应失败。
nonce
是随机值。随机值次要是为了减少sign
的多变性,也能够爱护接口的幂等性,相邻的两次申请nonce
不容许反复,如果反复则认为是反复提交,响应失败。
sign
是参数签名,将appkey
,timestamp
,nonce
拼接起来进行md5加密(当然应用其余形式进行不可逆加密也没问题)。
token
,应用参数appid
,timestamp
,nonce
,sign
来获取token,作为零碎调用的惟一凭证。token
能够设置一次无效(这样安全性更高),也能够设置时效性,这里举荐设置时效性。如果一次无效的话这个接口的申请频率可能会很高。token
举荐加到申请头上,这样能够跟业务参数齐全辨别开来。
1.2 应用POST作为接口申请形式
个别调用接口最罕用的两种形式就是GET和POST。两者的区别也很显著,GET申请会将参数裸露在浏览器URL中,而且对长度也有限度。为了更高的安全性,所有接口都采纳POST形式申请。
1.3 客户端IP白名单
ip白名单是指将接口的拜访权限对局部ip进行凋谢。这样就能防止其余ip进行拜访攻打,设置ip白名单比拟麻烦的一点就是当你的客户端进行迁徙后,就须要从新分割服务提供者增加新的ip白名单。设置ip白名单的形式很多,除了传统的防火墙之外,spring cloud alibaba提供的组件sentinel也反对白名单设置。为了升高api的复杂度,举荐应用防火墙规定进行白名单设置。
1.4 单个接口针对ip限流
限流是为了更好的保护零碎稳定性。应用redis进行接口调用次数统计,ip+接口地址作为key,拜访次数作为value,每次申请value+1,设置过期时长来限度接口的调用频率。
1.5 记录接口申请日志
应用aop全局记录申请日志,疾速定位异样申请地位,排查问题起因。
1.6 敏感数据脱敏
在接口调用过程中,可能会波及到订单号等敏感数据,这类数据通常须要脱敏解决,最罕用的形式就是加密。加密形式应用安全性比拟高的RSA
非对称加密。非对称加密算法有两个密钥,这两个密钥齐全不同但又齐全匹配。只有应用匹配的一对公钥和私钥,能力实现对明文的加密和解密过程。
二 幂等性问题
幂等性是指任意屡次申请的执行后果和一次申请的执行后果所产生的影响雷同。说的直白一点就是查问操作无论查问多少次都不会影响数据自身,因而查问操作自身就是幂等的。然而新增操作,每执行一次数据库就会发生变化,所以它是非幂等的。
幂等问题的解决有很多思路,这里讲一种比拟谨严的。提供一个生成随机数的接口,随机数全局惟一。调用接口的时候带入随机数。第一次调用,业务解决胜利后,将随机数作为key,操作后果作为value,存入redis,同时设置过期时长。第二次调用,查问redis,如果key存在,则证实是反复提交,间接返回谬误。
三 数据标准问题
3.1 版本控制
一套成熟的API文档,一旦公布是不容许随便批改接口的。这时候如果想新增或者批改接口,就须要退出版本控制,版本号能够是整数类型,也能够是浮点数类型。个别接口地址都会带上版本号,http://ip:port//v1/list。
3.2 响应状态码标准
一个牛逼的API,还须要提供简单明了的响应值,依据状态码就能够大略晓得问题所在。咱们采纳http的状态码进行数据封装,例如200示意申请胜利,4xx示意客户端谬误,5xx示意服务器外部产生谬误。状态码设计参考如下:
分类 | 形容 |
---|---|
1xx | 信息,服务器收到申请,须要请求者继续执行操作 |
2xx | 胜利 |
3xx | 重定向,须要进一步的操作以实现申请 |
4xx | 客户端谬误,申请蕴含语法错误或无奈实现申请 |
5xx | 服务端谬误 |
状态码枚举类:
public enum CodeEnum { // 依据业务需要进行增加 SUCCESS(200,"解决胜利"), ERROR_PATH(404,"申请地址谬误"), ERROR_SERVER(505,"服务器外部产生谬误"); private int code; private String message; CodeEnum(int code, String message) { this.code = code; this.message = message; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; }}
3.3 对立响应数据格式
为了不便给客户端响应,响应数据会蕴含三个属性,状态码(code),信息形容(message),响应数据(data)。客户端依据状态码及信息形容可疾速晓得接口,如果状态码返回胜利,再开始解决数据。
响应后果定义及罕用办法:
public class R implements Serializable { private static final long serialVersionUID = 793034041048451317L; private int code; private String message; private Object data = null; public int getCode() { return code; } public void setCode(int code) { this.code = code; } public String getMessage() { return message; } public void setMessage(String message) { this.message = message; } public Object getData() { return data; } /** * 放入响应枚举 */ public R fillCode(CodeEnum codeEnum){ this.setCode(codeEnum.getCode()); this.setMessage(codeEnum.getMessage()); return this; } /** * 放入响应码及信息 */ public R fillCode(int code, String message){ this.setCode(code); this.setMessage(message); return this; } /** * 解决胜利,放入自定义业务数据汇合 */ public R fillData(Object data) { this.setCode(CodeEnum.SUCCESS.getCode()); this.setMessage(CodeEnum.SUCCESS.getMessage()); this.data = data; return this; }}
总结
本篇文章从安全性、幂等性、数据标准等方面探讨了API设计规范。除此之外,一个好的API还少不了一个优良的接口文档。接口文档的可读性十分重要,尽管很多程序员都不喜爱写文档,而且不喜爱他人不写文档。为了不减少程序员的压力,举荐应用swagger或其余接口管理工具,通过简略配置,就能够在开发中测试接口的连通性,上线后也能够生成离线文档用于治理API。
点关注、不迷路
如果感觉文章不错,欢送关注、点赞、珍藏,你们的反对是我创作的能源,感激大家。
如果文章写的有问题,请不要悭吝,欢送留言指出,我会及时核查批改。
如果你还想更加深刻的理解我,能够微信搜寻「Java旅途」进行关注。回复「1024」即可取得学习视频及精美电子书。每天7:30准时推送技术文章,让你的下班路不在孤单,而且每月还有送书流动,助你晋升硬实力!