API设计原则
- 轻量级
- 适合跨操作系统
- 易于开发
- 易于测试
- 易于部署
API安全防护
1.防伪装攻击:第三方 有意或恶意 的调用我们的接口
2.防篡改攻击:请求头/参数 在传输过程被修改
3.防重放攻击:请求被截获,数据原封不动的发送给接收方
4.防数据信息泄漏:截获请求值/返回值,截获到账号、密码等敏感数据
设计原则就不多说了,以下主要说下API得防护。
以下是具体API防护的整体思路:
防止伪装攻击
- 防伪令牌可以避免伪装攻击。
防止篡改攻击
- 签名是防止参数被篡改的一种验证方式
如果参数项/参数值被修改,修改的请求参数最后验签肯定是false
防重放攻击
- 随机字符串:唯一数据或者可以视为一段时间内的唯一数据
随机字符串为什么可以防止重放攻击呢?如果每次请求都先判断一下缓存是否存在,如果存在则认为该请求是重复请求的;如果不存在则把随机字符串存储在缓存中。这样就可以避免重放攻击的请求数据。
有一点需要注意是如果在不考虑性能的前提下,可以不使用【时间参数】,所有随机字符串只做存储不做删除,但是这样存储的集合越来越大并且几个月几天前的数据本质上是没什么用的。所以我们使用随机字符串+时间参数来防止重放攻击。
- 时间参数:当前时间的yyyyMMddHHmmss
我们假设只存储随机字符串1分钟,那么在一分钟内重放攻击是可以避免掉的,但是超出1分钟之后重放攻击请求的数据则被认为是有效的请求。所以我们一般使用时间参数来互补这一点。如果时间参数与当前服务器的时间差>=60s 则认为是无效的请求(PS:一般一个请求是瞬间连接成功);<60s的话则认为是有效的请求,这时候要判断随机字符验证了。我个人认为时间参数的间隔时间应该与缓存时间是一致的。至于能不能大于缓存时间,你们可以思考下???
可以这么理解:随机字符串可以解决在有效的时间范围内数据一致性的的问题,时间参数可以解决随机字符串集合越来越大的问题。
那么问题来了,你们也许有疑问,我只用签名不可以吗?
其实签名可以验证参数篡改的情况,但是如果我获取到请求的值原封不动的攻击这个API,这时候只有签名的话会认为该请求是ok的。所以我们上述说了,防止篡改攻击+防止重放攻击=签名+随机字符串+时间戳
关于为什么有用户标识的问题就不多说了。。。
以下是大概的流程图:
至于代码怎么实现,我发布过关于本文的相关知识点,有兴趣的可以参考下