laravel接口频率详细
# 在 Laravel 中,throttle
(速率限制)功能可以帮助限制对 API 的访问频率,以防止滥用。
# 默认设置
在 Laravel 中,默认的速率限制设置通常在 app/Http/Kernel.php
文件中定义。它使用了 ThrottleRequests
中间件。
# 默认速率限制
默认速率限制: Laravel 默认情况下对所有 API 路由应用了限速,限制为每分钟 60 次请求。
实现: 通过
api
中间件组应用速率限制。以下是默认配置的示例:protected $middlewareGroups = [ 'api' => [ 'throttle:60,1', // 限制每分钟 60 次请求 \Illuminate\Routing\Middleware\SubstituteBindings::class, ], ];
1
2
3
4
5
6
# 自定义设置
你可以根据需要自定义速率限制。以下是一些常见的自定义设置方法:
# 1. 修改默认限制
如果你希望更改默认的速率限制,可以在 app/Http/Kernel.php
文件中修改 throttle
中间件的参数。例如,将限制更改为每分钟 100 次请求:
protected $middlewareGroups = [
'api' => [
'throttle:100,1', // 限制每分钟 100 次请求
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
2
3
4
5
6
# 2. 为特定路由设置不同的限制
如果你希望为特定的路由设置不同的速率限制,可以在路由定义中使用 throttle
中间件。例如:
use Illuminate\Support\Facades\Route;
Route::middleware(['throttle:10,1'])->group(function () {
Route::get('/special-api', 'ApiController@specialMethod');
});
2
3
4
5
在这个例子中,/special-api
路由的请求被限制为每分钟 10 次。
# 3. 自定义限速逻辑
如果你需要更复杂的限速逻辑,可以创建自己的中间件来处理速率限制。以下是一个简单示例:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Cache;
class CustomThrottle
{
public function handle($request, Closure $next)
{
$key = 'throttle:' . $request->ip();
$maxAttempts = 5;
$decayMinutes = 1;
if (Cache::has($key) && Cache::get($key) >= $maxAttempts) {
return response()->json(['message' => 'Too Many Requests'], 429);
}
Cache::increment($key);
Cache::put($key, Cache::get($key), now()->addMinutes($decayMinutes));
return $next($request);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
在这个例子中,自定义的 CustomThrottle
中间件限制每个 IP 每分钟最多只能请求 5 次。
# 4. 使用配置文件
你也可以在 config/throttle.php
中配置限速参数,将其作为全局配置使用:
return [
'global' => [
'limit' => 60,
'time' => 1,
],
'routes' => [
'special-api' => [
'limit' => 10,
'time' => 1,
],
],
];
2
3
4
5
6
7
8
9
10
11
12
然后在中间件中读取这些配置。
# 总结
- 默认速率限制: 每分钟 60 次请求。
- 自定义限制: 可以通过修改中间件参数或为特定路由设置不同的限制来实现。
- 自定义限速逻辑: 可以创建新的中间件实现更复杂的限制逻辑。
要实现每分钟最多 10 次请求的 Redis 速率限制逻辑,通常需要使用 Redis 来存储请求计数和过期时间。以下是详细的分析和步骤:
# 逻辑分析
- 请求计数:每当用户发起请求时,系统会增加一个计数器。
- 过期时间:计数器需要在每分钟后失效,确保在新的一分钟开始时重新计数。
- 限制检查:在每次请求时,检查当前计数器的值。如果超过最大请求次数(例如 10 次),则拒绝请求,返回相应的错误信息(例如 429 Too Many Requests)。
# 自定义频率中间件
# 1. 使用 Redis 客户端连接
确保你的 Laravel 项目已经配置好 Redis。在 config/database.php
中,你可以看到 Redis 配置:
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
2
3
4
5
6
7
8
9
10
11
# 2. 创建速率限制中间件
接下来,创建一个中间件来实现速率限制逻辑:
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Redis;
class RateLimiter
{
public function handle($request, Closure $next)
{
$key = 'rate_limiter:' . $request->ip(); // 使用用户的 IP 作为唯一标识
$maxAttempts = 10; // 最大请求次数
$decayMinutes = 1; // 过期时间(分钟)
// 获取当前请求计数
$currentAttempts = Redis::get($key);
// 检查是否超过最大请求次数
if ($currentAttempts >= $maxAttempts) {
return response()->json(['message' => 'Too Many Requests'], 429);
}
// 增加请求计数
Redis::incr($key);
// 如果是第一次请求,设置过期时间
if ($currentAttempts == 0) {
Redis::expire($key, $decayMinutes * 60); // 设置过期时间(秒)
}
return $next($request);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# 3. 注册中间件
在 app/Http/Kernel.php
中注册新创建的中间件:
protected $routeMiddleware = [
// ...
'rate.limiter' => \App\Http\Middleware\RateLimiter::class,
];
2
3
4
# 4. 应用中间件
你可以将中间件应用于特定的路由或路由组。例如:
use Illuminate\Support\Facades\Route;
Route::middleware(['rate.limiter'])->group(function () {
Route::get('/api/resource', 'ApiController@resource');
});
2
3
4
5
# 总结
- 计数器:使用 Redis 键存储请求计数。
- 过期管理:设置适当的过期时间以重置计数器。
- 请求检查:在每次请求时检查计数器值并相应地处理请求。