素材牛VIP会员
怎么保证对外暴露接口的安全性(调用频率限制)
 素***2  分类:PHP代码  人气:1714  回帖:11  发布于6年前 收藏

如何限制接口调用者对接口的调用频率?

问题:对某个对外暴露的接口加一个限制:调用者一分钟之内调用次数不能超过100次,如果超过100次就直接返回给调用者失败的信息。

  • 给调用者一个SECRET,每次调用者需要调用接口的时候,都需要把这个SECRET带过来(为了安全需要对key进行一系列加密的措施)

  • 一个SECRET就代表一个调用者,把相应的SECRET的调用次数放入缓存中(必须确保次数增加的原子性),并且把SECRET当做缓存的SECRET(这里如果区分方法的话,可以把方法和KEY做一次加密)。

这里主要的难点就是,如何判断调用者1分钟之内调用次数是否超过100?也就是很难确实这个1分钟的开始时间。

我现在的想法是:分别把当前秒调用的次数存入缓存。比如说,当前调用者调用次数为3,那么我就往缓存中加入KEY=SECRET_1,VALUE=3;然后调用者在第二秒调用的次数为4,那么就往缓存中加入KEY=SECRET_2,VALUE=3;如此循环,当循环到61秒的时候替换KEY=SECRET_1中得VAALUE,每次调用的时候计算SECRET_1~SECRET_60的值来判断调用次数,是否超过100次。(这里具体一秒钟调用几次,需要通过时间戳来算出是第几秒。这里以60秒为时间周期,并且以秒为一个时间单位,当然如果要求不是很准确的话,时间单位可以调大一点)

问题 请问有没有别的更好方法或者想法可以实现这个调用频率的限制?

Update:基于令牌桶的开放平台限流框架:limiter,持续开发中...

讨论这个帖子(11)垃圾回帖将一律封号处理……

Lv3 码奴
二***了 交互设计师 6年前#1

可否创建一个计数器,在cache中set一个key(根据用户标识)=0,设置timeout=60s,这样,新的请求到来,判断是否存在这个key,如果存在key,value>100,则拒绝请求,如果<100,则将其value+1,如果key不存在,则重新set一次,初始值为0,执行请求

Lv5 码农
us***es 职业无 6年前#2

Redid 的expire功能完全可以满足你的需求

Lv6 码匠
Ga***er 软件测试工程师 6年前#3

这个呢?
Redis 与网络流量整形
http://blog.jobbole.com/88064/

Lv6 码匠
飞***猪 交互设计师 6年前#4

实现一个栈,存放请求信息,请求来源地或者来源用户,以及请求时间。

然后处理请求就是,系统当前时间向前规定时间内的请求出栈,以供处理。

由于后进先出的选择,出栈的请求应当是按时间顺序倒序排列。然后再统计这些数据中同源数据的个数,小于规定数目的向后转发进行处理,大于规定数目的返回超限的响应。

上述的操作在拦截器或者过滤器中完成。题主觉得这样的思路可行么?

Lv6 码匠
Ga***er 软件测试工程师 6年前#5

我的想法是这样的:
为每个SECRET维护一个固定60秒的数组, key为每秒的时间(key_1: 第一秒的UNIX时间戳, key_2: 第二秒的UNIX时间戳), value为每秒访问的次数, value的默认值为0.
如果访问时间在这个数组中(通过key_1 + 60来进行判断), 则找到对应的key, 例如key_n.判断由key_1 + ... + key_n的总和是否大于100, 如果小于100, 则key_n++
如果访问时间不在这个数组中, 数组进行初始化, key_1为当前访问时间对应的第一秒的值, 例如当前访问时间为: 2015-06-29 17:09:30, 则key_1为2015-06-29 17:09:01对应的UNIX时间戳

Lv3 码奴
xi***xu 职业无 6年前#6

赞同令牌桶,另外这里有算法,只需要记录一个数据:What's a good rate limiting algorithm?

Lv3 码奴
上***水 职业无 6年前#7

令牌桶

====
令牌桶算法是网络流量整形(Traffic Shaping)和速率限制(Rate Limiting)中最常使用的一种算法。典型情况下,令牌桶算法用来控制发送到网络上的数据的数目,并允许突发数据的发送。

Lv3 码奴
空***子 职业无 6年前#8

为每个secret维护一个长度为100的队列
当队列长度为100的时候,取出队列头
判断时间是否超过1分钟,则accept
如果不足1分钟则deny
然后shift和push队列即可

Lv5 码农
Co***ht 软件测试工程师 6年前#9

接口请求频率,你最后采取的什么方案?谢谢

Lv5 码农
zh***ao 职业无 6年前#10

nginx的limit_req_zone就符合你想要的这种需求,它是使用令牌桶算法的.具体你可以看一下.

上一页12下一页
 文明上网,理性发言!   😉 阿里云幸运券,戳我领取