Laravel 5.2 新特性系列 —— 访问频率限制中间件throttle的使用

1、访问频率限制概述

频率限制经常用在API中,用于限制独立请求者对特定API的请求频率。例如,如果设置频率限制为每分钟1000次,如果一分钟内超过这个限制,那么服务器就会返回 429: Too Many Attempts.响应。

通常,一个编码良好的、实现了频率限制的应用还会回传三个响应头: X-RateLimit-LimitX-RateLimit-RemainingRetry-After(如果达到限制次数只能获取到 Retry-After头)。 X-RateLimit-Limit告诉我们在指定时间内允许的最大请求次数, X-RateLimit-Remaining指的是在指定时间段内剩下的请求次数, Retry-After指的是距离下次重试请求需要等待的时间(s)。

注意:每个API都会选择一个自己的频率限制时间跨度,GitHub选择的是1小时,Twitter选择的是15分钟,Laravel中间件选择的是1分钟。

2、如何使用Laravel的访问频率限制中间件

在Laravel 5.2的新特性中,你可以使用一个新的中间件 throttle,让我们先来看看这个中间件的用法,首先我们定义一个路由规则如下:

Route::group(['prefix'=>'api'],function(){
    Route::get('users',function(){
        return \App\User::all();
    });
});

然后我们将中间件throttle添加到其中,throttle默认限制每分钟尝试60次,并且在一分钟内访问次数达到60次后禁止访问:

Route::group(['prefix'=>'api','middleware'=>'throttle'],function(){
    Route::get('users',function(){
        return \App\User::all();
    });
});

如果你访问api/users路由,就会看到响应头如下所示:

Laravel throttle中间件使用

该响应意味着:

  • 请求成功(状态码为200)
  • 每分钟只能访问60次
  • 在本时间段内还能访问57次

如果访问次数超过60次,响应头如下:

Laravel throttle中间件使用

同时,响应内容文本为:Too Many Attempts。

如果44s后重试,页面恢复正常访问。

3、自定义throttle中间件

让我们来做一点自定义,现在我们想要限制每分钟访问5次:

Route::group(['prefix'=>'api','middleware'=>'throttle:5'],function(){
    Route::get('users',function(){
        return \App\User::all();
    });
});

如果我们想要改变达到指定限制次数后的等待时间,可以这样自定义:

Route::group(['prefix'=>'api','middleware'=>'throttle:5,10'],function(){
    Route::get('users',function(){
        return \App\User::all();
    });
});

学院君 has written 980 articles

Laravel学院院长,终身学习者

积分:112637 等级:P12 职业:手艺人 城市:杭州

14 条回复

  1. 云窗 云窗 says:
    @ sycamore 请问这个可以实现么?
  2. twisted twisted says:
    @ 李虎啸 你好,解决这个问题了吗
  3. 张顺 张顺 says:
    这个特性 能直接移植到 5.1么? 直接添加'throttle' => IlluminateRoutingMiddlewareThrottleRequests::class, 到$routeMiddleware然后复制这个类文件到 5.1的对应文件夹?
  4. 小生我怕怕 小生我怕怕 says:
    该如何自定义触发之后的提示信息呢?
  5. 河岸的花- 河岸的花- says:
    有办法限制这种的吗?只限制id的不同,每个不同的id只能访问这个一次, 现在这样写,没实现效果Route::group(['middleware' => 'throttle:1,2'], function() { // 短信验证码 Route::get('pushnote/{id}', function($id) { return $id; }); });
  6. 佳佳 佳佳 says:
    怎么根据数据库中某个用户进行限制? 类似API接口 APPID对应的限制?
  7. FengBingji FengBingji says:
    请问可以设置单用户访问数量吗?

登录后才能进行评论,立即登录?