4

I have a Auth.Attempt event handler class, which I detect user's login attempts to decide to lock user's account. However, when I tried to redirect user to login page with a flash message, I found the redirection does not work, it's still carry on next step. I want to interrupt the process in the event and give my custom warning message. Can anyone help me out? Thanks a lot.

My event handler:

namespace MyApp\Handlers\Security;

use DB;
use Session;
use Redirect;

class LoginHandler 
{
    /**
     * Maximum attempts
     * If user tries to login but failed more than this number, User account will be locked
     * 
     * @var integer
     */
    private $max_attemtps;

    /**
     * Maximum attempts per IP
     * If an IP / Device tries to login but failed more than this number, the IP will be blocked
     * 
     * @var integer
     */
    private $ip_max_attempts;

    public function __construct()
    {
        $this->max_attempts = 10;
        $this->ip_max_attempts = 5;
    }

    public function onLoginAttempt($data)
    {
        //detection process.......
        // if login attempts more than max attempts
        return Redirect::to('/')->with('message', 'Your account has been locked.');
    }
}

Now the way I am doing this is like below:

Session::flash('message', 'Your account has been locked.');
header('Location: '.URL::to('/'));

It works but I am not sure if it's perfect way to do it.

Antonio Carlos Ribeiro
  • 86,191
  • 22
  • 213
  • 204
Jonathan
  • 538
  • 1
  • 6
  • 18
  • Why `use Redirect;` ? – The Alpha Jul 22 '13 at 23:24
  • Because I don't want to process Authentication. I try to validate the user login attempts before validating username and password. If user's account is locked or the IP is blocked, the process will be terminated and redirect to home page with a flash message. – Jonathan Jul 23 '13 at 01:25
  • No, I meant the `use Redirect` is this a valid namespace ? – The Alpha Jul 23 '13 at 01:27
  • Oh sorry I didn't see the "highlight" background. Yes it is. It's actually an alias of Illuminate\Support\Facades\Redirect which is predefined in app/config/app.php. I have dumped the Redirect::to() data, it's correct. But it just doesn't redirect in event handler. I don't know how to make it working. – Jonathan Jul 23 '13 at 02:07
  • Try to debug by placing two marks, one before the redirect call and one after it, is error reporting on, if not make it on by setting this on top `error_reporting(E_ALL); ini_set('display_errors', '1');`. – The Alpha Jul 23 '13 at 02:13
  • I have tried this. No error happens, it looks like the handler returns the Request object back, but the process still carries on and ignores the request. Probably there is no function handles Request object in Events. I haven't spent too much time on framework's code. So I probably can only go with my current solution. Thanks a lot for your help anyway. – Jonathan Jul 23 '13 at 03:39

2 Answers2

6

You can still send an HttpException who will work. But obviously instructions after the event handler will not be interpreted

abort(redirect('/'));
Léonard
  • 83
  • 1
  • 8
4

Not getting to much into this very interesting discussion:

Should exceptions be used for flow control

You can try setting up your own exception handler and redirect from there on to the login page.

class FancyException extends Exception {}

App::error(function(FancyException $e, $code, $fromConsole)
{
    $msg = $e->getMessage();        
    Log::error($msg);

    if ( $fromConsole )
    {
        return 'Error '.$code.': '.$msg."\n";
    }

    if (Config::get('app.debug') == false) {
        return Redirect::route('your.login.route');
    }
    else
    {
        //some debug stuff here
    }


});

And in your function:

public function onLoginAttempt($data)
{
    //detection process.......
    // if login attempts more than max attempts
    throw new FancyException("some msg here");
}
sepehr
  • 17,110
  • 7
  • 81
  • 119
Gadoma
  • 6,475
  • 1
  • 31
  • 34