Laravel 登入失败次数限制 等待时间递增

Laravel 本身已实现了登入失败次数限制的功能。在使用 Laravel 的登入验证时,登入失败次数限制预设是:

失败5次,1分钟后 才可再次登入

但如果要求的功能是:

 失败3次,1分钟后 才可登入再失败3次,3分钟后 才可登入再失败3次,5分钟后 才可登入...

要如何实现?下面将示範此登入失败次数限制的功能。

版本

Laravel 5.8 以上

改写登入类别设定

app\Http\Controllers\Auth\LoginController.php

<?php...use Illuminate\Foundation\Auth\AuthenticatesUsers;use Illuminate\Http\Request;use App\Cache\AdvancedRateLimiter;class LoginController extends Controller{    use AuthenticatesUsers;    ...    /**     * 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 = [1, 3, 5];    /**     * Get the rate limiter instance.     *     * @return \App\Cache\AdvancedRateLimiter     */    protected function limiter()    {        return app(AdvancedRateLimiter::class);    }    /**     * Increment the login attempts for the user.     *     * @param  \Illuminate\Http\Request  $request     * @return void     */    protected function incrementLoginAttempts(Request $request)    {        $this->limiter()->hit(            $this->throttleKey($request), array_map(function ($decayMinute) {                return (int) ($decayMinute * 60);            }, (array) $this->decayMinutes())        );    }}

LoginController 类中,增加自订方法覆盖 AuthenticatesUsers 类原本的方法:

limiter 方法是返回登入失败次数限制的类,原本是返回RateLimiter 类(实现登入失败次数限制的类),但本例要扩充新方法,因此返回了我们下面创建的子类别AdvancedRateLimiter $maxAttempts 属性是设定登入失败次数。$decayMinutes 属性是登入失败达上限后,须等待的分钟数。但我们要实现的功能是每次都等待不一样的时间,因此传入一个阵列,输入每次的等待分钟数。

如果只是要修改 Laravel 原本的错误次数设定,新增 $maxAttempts 属性及 $decayMinutes 属性并设定值即可完成。

扩充登入失败次数限制功能

新增类别 AdvancedRateLimiter

app\Cache\AdvancedRateLimiter.php

<?phpnamespace App\Cache;use Illuminate\Cache\RateLimiter;class AdvancedRateLimiter extends RateLimiter{    /**     * Increment the counter for a given key for a given decay time.     *     * @param  string  $key     * @param  int|int[]  $decaySeconds     * @return int     */    public function hit($key, $decaySeconds = 60)    {        if (is_array($decaySeconds)) {            if (! $this->cache->has($key.':timer')) {                if (! $this->cache->has($key.':step')) {                    $this->cache->add($key.':step', 0, 86400);                } else {                    $this->cache->increment($key.':step');                }            }            $step = $this->cache->get($key.':step', 0);            $step = $step < count($decaySeconds) ? $step : count($decaySeconds) - 1;            $decaySeconds = $decaySeconds[$step];        }        return parent::hit($key, $decaySeconds);    }    /**     * Clear the hits and lockout timer for the given key.     *     * @param  string  $key     * @return void     */    public function clear($key)    {        $this->cache->forget($key.':step');        parent::clear($key);    }}
hit 方法是在登入错误后,执行登入错误次数记录递增的方法。为了实现每次登入错误等待的时间可以不一样,我们让传入的变数 $decayMinutes 可以接受传入阵列,第一次登入错误等待时间为 阵列[0] 的分钟数(本例为1分钟),第二次为 阵列[1] 的分钟数(例:3分钟),而第三次为 阵列[2] 的分钟数(例:5分钟),之后的登入错误等待时间皆为阵列的最后的元素的分钟数。clear 方法是成功登入后,将时间、次数重设,下一次再登入错误后,将从头开始计数。

此时登入失败次数限制的功能已改写完成,再次登入并输入错误的帐号或密码,重複数次即可看到结果。


关于作者: 网站小编

码农网专注IT技术教程资源分享平台,学习资源下载网站,58码农网包含计算机技术、网站程序源码下载、编程技术论坛、互联网资源下载等产品服务,提供原创、优质、完整内容的专业码农交流分享平台。

热门文章