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
@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
}
}
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.. ^_^
The easiest way.
In your Auth filter use the following:
Route::filter('sentryAuth', function()
{
if ( ! Sentry::check())
{
return Redirect::guest(route('login'));
}
});
In your controller:
public function postAuthenticate()
{
try {
$credentials = array(
'email' => Input::get('email'),
'password' => Input::get('password')
);
$user = Sentry::authenticate($credentials, false);
} catch () {
// validation errors
}
//firstly, Laravel will try to redirect intended page.
//if nothing saved in session, it will redirect to home.
//you can use any route instead of home.
return Redirect::intended(route('home'));
}
Done.
Outside of Sentry:
This code can be used with any type of authentication library. You need two things to implement intended redirection:
1.in your auth filter:
Route::filter('auth', function() { if ( ! Sentry::check()) { return Redirect::guest(route('login')); } });
2.After logged in an user:
//firstly, Laravel will try to redirect intended page. //if nothing saved in session, it will redirect to home. //you can use any url instead of '/' return Redirect::intended('/');
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.