前面我们有讲过如何进行API的安全控制,其中包括数据加密,接口签名等内容。详细可以参考我下面两篇文章:
在签名部分,通过时间戳的方式来判断当前请求是否有效,目的是为了防止接口被多次使用。但是这样并不能保证每次请求都是一次性的,今天给大家介绍下如何保证请求一次性?
首先我们来回顾一些时间戳判断的原理:客户端每次请求时,都需要进行签名操作,签名中会加上signTime参数(当前请求时间戳)。HTTP请求从发出到达服务器的正常时间不会很长,当服务器收到HTTP请求之后,首先进行签名检查,通过之后判断时间戳与当前时间相比较,是否超过了一定的时间,这个时间我们可以自行决定要多长,比如1分钟,2分钟都可以,时间长点可以防止客户端和服务器时间不一致的问题,如果超过了则认为是非法的请求。
假设我们的请求有效期是1分钟,如果黑客得到了我们的请求地址,在1分钟之内是可以重复请求多次的,因为这种方式不能保证请求仅一次有效。
基于nonce的方式可以解决重复使用的问题,最开始知道nonce是在广点通的接口中看到的,如下图所示:
1.png
可以看到腾讯这边的接口也是基于时间戳和nonce来控制的。
nonce是随机字符串,每次请求时都要保证不同,你可以用uuid,可以用别的算法,也可以用随机加时间戳等等,只要不重复就行。
在后端我们验证的时候,将nonce参数存储起来,至于是存储在本地内存中,数据库中,redis,布隆过滤器中这就看你自己的需求了。
处理HTTP请求时,首先判断该请求的nonce参数是否在存在,如果存在则认为是非法请求。如果不存在则是合法请求,让后将该nonce存储起来,防止下次重复使用。
这种方式的弊端也很明显,那就是nonce的存储会越来越大,验证nonce是否存在的时间会越来越长。
如何解决存储问题?
可以用时间戳+nonce同时使用,相互配合,取长补短。
首先我们根据时间戳判断是否超过了一定的时间范围,如果超过了就直接拒绝,没有超过继续验证nonce是否使用过。
nonce没使用,存储起来,记录一个存储时间,通过定时任务去清除超过了时间戳验证的时间的nonce。这样的话我们只需要存储固定时间内的nonce数据,因为时间长的已经被时间戳的判断给拦截了,nonce的验证只需要验证时间有效期内的即可。
伪代码如下:
领取专属 10元无门槛券
私享最新 技术干货