如何优雅的实现接口防刷,看过来!!!

在我们的app、网站等互联网应用系统中,如果接口直接暴露在外网下,是存在着接口安全问题的。当我们的接口没有任何防刷的措施,就相当于在互联网上裸奔一样!当被一些不怀好意的人利用,那就是发生灾难的时候了!

那应该怎么确保我们的接口安全呢?

通常来说,我们将对外的api接口,做到防重放以及防篡改,这样才能保证我们接口的基本安全!

防重放

防重放又名防复用。也就是我们在收集到一个请求的参数信息后,不做任何修改,将这些参数直接重复请求这个接口。这个时候我们的请求是合法的,毕竟我们的参数都是一致的。

重放带来的2中后果:

1、查询接口:这种后果是比较致命的,甚至可以让你的系统崩溃。重点的攻击对象就是man查询接口,加入一个接口查询是2S,我不对的对你发起查询,就会导致系统的数据库查询阻塞,从而导致系统崩溃

2、新增数据接口:这种攻击方式会造成我们数据库的垃圾数据增加,从而将数据库表撑到崩溃!

针对如上两种后果,我们如果破局呢?

时间戳timetamp

当发起HTTP请求的时候,必须携带一个timestamp参数,然后将这timestamp参数和其他的参数按照一定的规则进行签名。毕竟,一次正常的HTTP请求,从点击发送到服务器处理一般都会在60S内,当服务端收到了这次请求后,先对timestamp参数与当前时间进行比较,假如超过了60S则被判定是为非法请求。

我们的签名就是为了防止攻击者对我们的timestamp人工更改所作的措施,毕竟攻击者从抓包到重放请求已经远超过了60S,这个时候参数中的timestamp已经过期了,如果攻击者更改时间错,则数字签名就会校验失败。因为,攻击者是不知道签名秘钥的。也就无法生成新的签名字符串。

大致流程如下图:

如何优雅的实现接口防刷,看过来!!!_第1张图片

这种方案是有弊端的,就是如果在60S内完成了重放攻击,name我们这种方案是无法得到有效的扼杀的!因为他不能保证请求数据只有一次有效。

时间戳timetamp+nonceStr

这里的nonceStr指的是:仅仅一次有效的随机字符串,每一次请求接口都是不一样的数据。这里给一个方案:随机数+时间戳+用户的唯一信息,拼接后进行哈希处理得到nonceStr。

这个方案的api端处理流程如下:

1、在缓存中查找是否有对应的key,key为nonceStr:{nonceStr}的一个字符串

2、没有这个key的时候,创建key。并且将key的失效时间和timestamp的失效时间设置成一样的。例如:60S

3、假如有这个key,说明这个key在60S内已经调用过接口,那么接口就会被认定为重放,则进行过滤处理!

流程图如下:

如何优雅的实现接口防刷,看过来!!!_第2张图片

这一方案,timestamp和nonceStr两者作为签名的一部分传到了后端,鉴于上面的timestamp方案使得攻击者只能在60S内进行了重放攻击操作,我们有通过了nonceStr随机数进行了60S内只能进行一次接口调用,则保证了我们接口避免重放攻击的漏洞!

防篡改

众所周知,HTTP他是一种无状态的请求协议,api接口并不会知道客户端发送的请求是否为合法请求,而且也不会知道请求携带的参数是否为有效参数。

比如,我们Sass多租户系统中,查询自己店铺的用户数据

http://localhost/api/store/user?store_id=101

这个接口如果被攻击者知道了, 则他可以通过更改门店ID的编码查询任意门店的用户信息。这就不是我们所想要的结果了!

解决方案

1、api接口对请求的参数进行校验,防止攻击者对参数进行更改

流程图如下:

如何优雅的实现接口防刷,看过来!!!_第3张图片

具体步骤如下:

1)、客户端使用提前生成的秘钥对传输参数按照一定的规则进行加密操作,得到签名值,将签名数据作为请求参数,发送给请求接口。

2)、api接口收到客户端的请求后,使用秘钥对请求参数(除了签名值)按照之前约定的规则进行签名,得到签名值

3)、将请求过来的签名值与我们接口生成的签名值进行比较,如果不一致,则认定为非法篡改请求。

2、采用https方式将接口数据进行加密后传输。

欢迎点击下方卡片,关注《coder练习生》

你可能感兴趣的:(服务器,网络,安全)