Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

laravel sentry redirect::intended not working

I'm trying to get the sentry package set up in my app correctly.

I can log a user in and out and protect routes but I can't seem to get the redirect::intended to work properly. My understanding is that a user will be taken back to the route they originally called before being directed to the login page. At the moment it simply keeps redirecting to the default page.

In my routes.php I have the following group set up:

Route::group(array('before' => 'sentryAuth'), function () {...}

Within this group I've placed all the protected routes.

In my filters.php I have the following filters:

Route::filter('sentryAuth', function () {

if (!Sentry::check()) {

    return Redirect::route('login');
} 
});

Route::filter('sentryGuest', function () {

if (Sentry::check()) {
    return Redirect::intended('dashboard');
}
});

In my userController I have the following code:

public function postAuthenticate()
{
    try {
        // Set login credentials
        $credentials = array(
            'email' => Input::get('email'),
            'password' => Input::get('password')
        );

        // Try to authenticate the user
        $user = Sentry::authenticate($credentials, false);
    } catch (Cartalyst\Sentry\Users\LoginRequiredException $e) {
        echo 'Login field is required.';
    }
    catch (Cartalyst\Sentry\Users\PasswordRequiredException $e) {
        echo 'Password field is required.';
    }
    catch (Cartalyst\Sentry\Users\UserNotFoundException $e) {
        echo 'User was not found.';
    }
    catch (Cartalyst\Sentry\Users\WrongPasswordException $e) {
        echo 'Wrong password, try again.';
    }
    catch (Cartalyst\Sentry\Users\UserNotActivatedException $e) {
        echo 'User is not activated.';
    }

    if (!Sentry::check()) {
        return Redirect::to('user/login');
    } else {
        return Redirect::intended('dashboard');
    }
}

I've tried to access a page 'bookings/create' without being logged in. I get taken to the login page, log in but it then takes me to the dashboard not to bookings/create.

AM I missing something here? Is there additional code I need to get the intended to work??

like image 500
Ray Avatar asked Sep 27 '13 23:09

Ray


3 Answers

In your filters.php make sure to use:

 return Redirect::guest('login');

instead of

 return Redirect::route('login');

The guest function will set the correct session variables for intended() to work properly.

like image 164
Tom Avatar answered Oct 19 '22 22:10

Tom


I am not sure about this, because I am not using Sentry for my current project.. so this is just a hunch.

It seems that since you used SentryAuth and not the native Auth class in laravel 4, the session item for the intended url is not set.. I looked on the API on the Redirector class and i saw this:

public function intended($default, $status = 302, $headers = array(), $secure = null)
{
    $path = $this->session->get('url.intended', $default);

    $this->session->forget('url.intended');

    return $this->to($path, $status, $headers, $secure);
}

and as the code says, the session key is 'url.intended'. i verified this using the native Auth filter and the intended URL is set on Session::get('url.intended') as expected..

so a possible solution to this is to manually set it in the session. an example would be:

On your filter

Route::filter('sentryAuth', function () {

    if (!Sentry::check()) {
        Session::put('loginRedirect', Request::url());
        return Redirect::route('login');
    } 
});

On your postAuthenticate() method

if (!Sentry::check()) {
    return Redirect::to('user/login');
} else {
    // Get the page we were before
    $redirect = Session::get('loginRedirect', 'dashboard');

    // Unset the page we were before from the session
    Session::forget('loginRedirect');

    return Redirect::to($redirect);
}

parts of the code were taken from here for reference.. ^_^

like image 21
reikyoushin Avatar answered Oct 19 '22 22:10

reikyoushin


@reikyoushin's answer is excellent. Here's a slightly different version.

routes.php

// NOTE: do NOT name your filter "auth" as it will not override
//       Laravel's built-in auth filter and will not get executed
Route::filter( 'sentryAuth', function()
{
    // check if logged in or not
    if ( ! Sentry::check() )
    {
        // the guest() method saves the intended URL in Session
        return Redirect::guest( 'user/login' );
    } else {
        // now check permissions for the given route
        $user = Sentry::getUser();
        if ( ! $user->hasAccess( Route::currentRouteName() ) )
        {
            // redirect to 403 page
            return Response::make( 'Forbidden', 403 );
        }
    }
});

// Protected routes
Route::group( array( 'before' => 'sentryAuth', function()
{
    Route::get( 'admin', function() { return View::make( 'admin.index' ); } );
});

and in your login function:

public function login() {
    try {
        $creds = array(
            'email'    => Input::get( 'email' ),
            'password' => Input::get( 'password' )
        );
        $user = Sentry::authenticate( $creds );
        return Redirect::intended( 'dashboard' );
    } catch ( Exception $e ) {
        // handle exceptions
    }
}
like image 4
morphatic Avatar answered Oct 20 '22 00:10

morphatic