Skip to content

Commit f680b9b

Browse files
authored
Merge pull request #7 from kylin987/main
自定义限流键
2 parents e95fd27 + 689639d commit f680b9b

File tree

3 files changed

+50
-1
lines changed

3 files changed

+50
-1
lines changed

README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,15 @@ Tinywan\LimitTraffic\RateLimiter::getRateLimit(); // 返回 [100, 600]
7373

7474
编辑 `config/plugin/tinywan/limit-traffic/app.php` 文件的 `status` HTTP 状态码(默认值是 `429`
7575

76+
### 自定义限流键
77+
78+
编辑 `config/plugin/tinywan/limit-traffic/app.php` 文件的 `limit_key` 限流键(默认值是 `none`
79+
80+
- `none 代表以ip作为限流键`
81+
- `get.id 代表以get请求的id作为限流键`
82+
- `post.access 代表以post请求的access作为限流键`
83+
- `header.token 代表以header请求的token作为限流键`
84+
7685
### 自定义`body`返回内容
7786

7887
编辑 `config/plugin/tinywan/limit-traffic/app.php` 文件的 `body` 的字段

src/RateLimiter.php

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ class RateLimiter
2424
public static function traffic()
2525
{
2626
$config = config('plugin.tinywan.limit-traffic.app.limit');
27+
// 新增:判断当前请求方法是否在配置的限流方法内
28+
if (isset($config['limit_method']) && is_array($config['limit_method'])) {
29+
if (!in_array(strtoupper(request()->method()), $config['limit_method'])) {
30+
// 当前请求方法不需要限流,直接返回 false 表示不过限
31+
return false;
32+
}
33+
}
2734
$scriptSha = Redis::get(self::LIMIT_TRAFFIC_SCRIPT_SHA);
2835
if (!$scriptSha) {
2936
$script = <<<luascript
@@ -41,7 +48,7 @@ public static function traffic()
4148
$scriptSha = Redis::script('load', $script);
4249
Redis::set(self::LIMIT_TRAFFIC_SCRIPT_SHA, $scriptSha);
4350
}
44-
$limitKey = self::LIMIT_TRAFFIC_PRE . request()->getRealIp();
51+
$limitKey = self::getLimitKey($config);
4552
$result = Redis::rawCommand('evalsha', $scriptSha, 1, $limitKey, $config['limit'], $config['window_time']);
4653
if ($result === 0) {
4754
return [
@@ -64,4 +71,35 @@ public static function getRateLimit(): array
6471
$config = config('plugin.tinywan.limit-traffic.app.limit');
6572
return [$config['limit'], $config['window_time']];
6673
}
74+
75+
/**
76+
* @desc: 获取限流key
77+
* @author kylin987
78+
*/
79+
private static function getLimitKey($config): string
80+
{
81+
$limitKey = $config['limit_key'] ?? '';
82+
// 默认按 IP 限流
83+
if (empty($limitKey) || $limitKey === 'none') {
84+
return self::LIMIT_TRAFFIC_PRE . md5(request()->getRealIp());
85+
}
86+
// 按 "来源.字段名" 拆分
87+
[$source, $key] = explode('.', $limitKey . '.', 2);
88+
89+
switch (strtolower($source)) {
90+
case 'get':
91+
$keyValue = request()->get($key, 'none');
92+
break;
93+
case 'post':
94+
$keyValue = request()->post($key, 'none');
95+
break;
96+
case 'header':
97+
$keyValue = request()->header($key, 'none');
98+
break;
99+
default:
100+
// fallback:IP
101+
$keyValue = request()->getRealIp();
102+
}
103+
return self::LIMIT_TRAFFIC_PRE . md5($keyValue);
104+
}
67105
}

src/config/plugin/tinywan/limit-traffic/app.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
return [
44
'enable' => true,
55
'limit' => [
6+
'limit_key' => 'none', // none:以ip地址为限流键,'get.id','header.X-Token','post.user_id',也可以自定义限流键
7+
'limit_method' => ['GET'], // 只限 GET
68
'limit' => 10, // 请求次数
79
'window_time' => 60, // 窗口时间,单位:秒
810
'status' => 429, // HTTP 状态码

0 commit comments

Comments
 (0)