7

我正在尝试在我的应用程序中正确设置哨兵包。

我可以登录和注销用户并保护路线,但我似乎无法redirect::intended正常工作。我的理解是,在被定向到登录页面之前,用户将被带回他们最初调用的路线。目前它只是继续重定向到默认页面。

在我的 routes.php 中,我设置了以下组:

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

在这个组中,我放置了所有受保护的路线。

在我的 filters.php 中,我有以下过滤器:

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

if (!Sentry::check()) {

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

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

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

在我的 userController 我有以下代码:

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');
    }
}

我尝试在未登录的情况下访问“预订/创建”页面。我被带到登录页面,登录但随后将我带到仪表板而不是预订/创建。

我在这里错过了什么吗?我需要额外的代码才能使预期工作吗?

4

4 回答 4

10

在您的 filters.php 中确保使用:

 return Redirect::guest('login');

代替

 return Redirect::route('login');

来宾函数将设置正确的会话变量,以使预期()正常工作。

于 2014-01-25T15:57:14.987 回答
8

我不确定这一点,因为我没有在我当前的项目中使用 Sentry。所以这只是一种预感。

似乎由于您在 laravel 4 中使用了 SentryAuth 而不是本机 Auth 类,因此未设置预期 url 的会话项。我查看了Redirector类的 API,我看到了这个:

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);
}

正如代码所说,会话密钥是“url.intended”。我使用本机身份验证过滤器验证了这一点,并且预期的 URL 已Session::get('url.intended')按预期设置。

所以一个可能的解决方案是在会话中手动设置它。一个例子是:

在你的过滤器上

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

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

在您的 postAuthenticate() 方法上

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);
}

部分代码取自here以供参考.. ^_^

于 2013-09-28T04:15:36.543 回答
4

@reikyoushin 的回答非常好。这是一个略有不同的版本。

路由.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' ); } );
});

并在您的登录功能中:

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
    }
}
于 2014-01-07T03:58:01.617 回答
0

最简单的方法。

在您的 Auth 过滤器中使用以下内容:

Route::filter('sentryAuth', function()
{
    if ( ! Sentry::check()) 
    {     
        return Redirect::guest(route('login'));
    }
});

在您的控制器中:

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'));
}

完毕。

哨兵之外:

此代码可用于任何类型的身份验证库。您需要两件事来实现预期的重定向:

1.在您的身份验证过滤器中:

    路由::filter('auth', function()
    {
      如果(!哨兵::检查())
          {
            return Redirect::guest(route('login'));
          }
    });

2.登录用户后:

//首先,Laravel 会尝试重定向目标页面。
//如果会话中没有保存任何内容,它将重定向到主页。
//你可以使用任何url代替'/'

return Redirect::intended('/');
于 2014-04-29T07:46:46.137 回答