Laravel : Increase time on second time login attempts

前端 未结 3 1619
死守一世寂寞
死守一世寂寞 2021-02-09 06:20

Currently five login attempts blocks user for 1 minute and its working fine with the following code :

if ($this->hasTooManyLoginAttempts($request)) {
    $thi         


        
相关标签:
3条回答
  • 2021-02-09 06:42

    I think you need to set property in LoginController:

    public $decayMinutes = 1; // minutes to lockout
    

    Also you can controll numbers of attempts:

    public $maxAttempts = 5;
    

    For more information you can investigate: trait AuthenticatesUsers - which has method "login" and code from your description. And this trait uses another trait: "ThrottlesLogins" -> this traits has method named "decayMinutes". It returns number of minutes.

    Hope it will help you!

    0 讨论(0)
  • 2021-02-09 06:50

    I would suggest you try the following code. Please ask if anything is unclear.

    $minutes = 3;
    $key = $this->throttleKey($request);
    $rateLimiter = $this->limiter();
    
    if ($this->hasTooManyLoginAttempts($request)) {
    
        $attempts = $rateLimiter->attempts($key); 
        if ($attempts > 1) {
            $attempts === 2 && $rateLimiter->clear($key);
            $this->decayMinutes = ($attempts - 1) * $minutes;
            $attempts === 2 && $this->incrementLoginAttempts($request);
            $this->incrementLoginAttempts($request);
        }
    
        $this->fireLockoutEvent($request);
        return $this->sendLockoutResponse($request);
    }
    

    Code for incremental blocking:

    $minutes = 3;
    $key = $this->throttleKey($request);
    $rateLimiter = $this->limiter();
    
    if ($this->hasTooManyLoginAttempts($request)) {
    
        $attempts = $rateLimiter->attempts($key);
        $rateLimiter->clear($key);
        $this->decayMinutes = $attempts === 1 ? 1 : ($attempts - 1) * $minutes;
    
        for ($i = 0; $i < $attempts; $i++) {
            $this->incrementLoginAttempts($request);
        }
    
        $this->fireLockoutEvent($request);
        return $this->sendLockoutResponse($request);
    }
    

    Code for incremental blocking with cache:

    $minutes = 3;
    $key = $this->throttleKey($request);
    $rateLimiter = $this->limiter();
    
    if ($this->hasTooManyLoginAttempts($request)) {
    
        $attempts = $rateLimiter->attempts($key);
        $rateLimiter->clear($key); // might have to add logic here
    
        $reflection = new \ReflectionClass($rateLimiter);
        $property = $reflection->getProperty('cache');
        $property->setAccessible(true);
        $cache = $property->getValue($rateLimiter);
        $reflectionMethod = new \ReflectionMethod($rateLimiter, 'availableAt');
        $reflectionMethod->setAccessible(true);
    
        $blockMinutes = $attempts === 1 ? 1 : $attempts > 1 ? ($attempts - 1) * $minutes : 1;
        $cache->add($key.':timer', $reflectionMethod->invoke($rateLimiter, $blockMinutes * 60), $blockMinutes);
        $added = $cache->add($key, 0, $blockMinutes);
        $hits = (int) $cache->increment($key, $attempts);
        if (! $added && $hits === 1) {
            $cache->put($key, 1, $blockMinutes);
        }
    
        $reflectionMethod->setAccessible(false);
        $property->setAccessible(false);
    
        $this->fireLockoutEvent($request);
        return $this->sendLockoutResponse($request);
    }
    
    0 讨论(0)
  • 2021-02-09 06:58

    I think laravel default doesn't provide what your need, So you need to save in (cache, session or database) if user had blocked once on your own, and increase decayMinutes as you want.

    if ($this->hasTooManyLoginAttempts($request)) {
        if(Cache::has($this->throttleKey($request))){
            $this->decayMinutes = 3;
        }
    
        Cache::put($this->throttleKey($request), true);
        $this->fireLockoutEvent($request);
    
        return $this->sendLockoutResponse($request);
    }
    
    0 讨论(0)
提交回复
热议问题