123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116 |
- <?php
- namespace App\Services;
- use Carbon\Carbon;
- use Illuminate\Http\Request;
- use Illuminate\Support\Facades\Cache;
- class AdvancedRateLimiterServices
- {
- /**
- * The maximum number of attempts to allow.
- *
- * @var int
- */
- protected $maxAttempts = 3;
- /**
- * The number of minutes to throttle for.
- *
- * @var int|float|int[]|float[]
- */
- protected $decayMinutes = [30, 60, 120];
- /**
- * 登录失败记录
- * @param Request $request
- * @param bool $maxAttempts
- * @param bool $decayMinutes
- * @return bool
- * Author: Mead
- */
- public function main(Request $request, $maxAttempts = false, $decayMinutes = false)
- {
- if (!$maxAttempts) {
- $maxAttempts = $this->maxAttempts;
- }
- if (!$decayMinutes) {
- $decayMinutes = $this->decayMinutes;
- }
- $key = $this->throttleKey($request);
- if (!Cache::has($key . ':step')) {
- Cache::add($key . ':step', 1, Carbon::parse(date('Y-m-d'))->addDays(1));
- } else {
- Cache::increment($key . ':step');
- }
- $nums = Cache::get($key . ':step', 1);
- if (!($nums % $maxAttempts)) {
- $step = $nums / $maxAttempts;
- $index = $step <= count($decayMinutes) ? ($step - 1) : false;
- if ($index === false) {
- $minutes = false;
- } else {
- $minutes = $decayMinutes[$index];
- }
- $time = str2arr(Cache::get($key . ':timer', ''));
- Cache::put($key . ':timer', php2js([
- 'time' => $minutes ? Carbon::now()->addMinutes($minutes)->toDateTimeString() : false,
- 'nums' => array_key_exists('time', $time) ? $time['time'] + 1 : 1
- ]), $minutes ? Carbon::now()->addMinutes($minutes) : Carbon::parse(date('Y-m-d'))->addDays(1));
- }
- return true;
- }
- /**
- * 获取key
- */
- public function throttleKey(Request $request)
- {
- return sha1(implode('|', array_merge(
- [$request->getMethod()],
- [$request->getHost(), $request->getUri(), $request->getClientIp()]
- )));
- }
- /**
- * 是否可以登录
- * @param Request $request
- * @return bool|string
- * Author: Mead
- */
- public function isLogin(Request $request)
- {
- $key = $this->throttleKey($request);
- $msg = false;
- if (Cache::has($key . ':timer')) {
- $msg = '今天尝试次数太多,请明天再试。';
- $re = js2php(Cache::get($key . ':timer', ''));
- if (array_key_exists('time', $re)) {
- if ($re['time'] != false) {
- $minutes = Carbon::parse($re['time'])->diffInMinutes(Carbon::now()) + 1;
- $msg = "尝试次数太多,请{$minutes}分钟后再试。";
- }
- }
- }
- return $msg;
- }
- /**
- * 清楚缓存
- * @param Request $request
- * Author: Mead
- */
- public function clear(Request $request)
- {
- $key = $this->throttleKey($request);
- Cache::forget($key . ':step');
- }
- }
|