问题
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??
回答1:
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.. ^_^
回答2:
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.
回答3:
@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
}
}
回答4:
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('/');
来源:https://stackoverflow.com/questions/19061507/laravel-sentry-redirectintended-not-working