如果在Laravel的内置身份验证中经过身份验证的逻辑重定向?

时间:2015-10-26 08:12:45

标签: php laravel authentication laravel-5.1

之前已经问过这个问题,我相信我的代码是正确的,但我的行为很奇怪。

我需要在登录后将用户重定向到不同的路由,具体取决于某些数据库值。我认为为了做到这一点,我只需将我的逻辑放在handle app/Http/Middleware/RedirectIfAuthenticated.php方法中。我的方法目前看起来像这样:

public function handle($request, Closure $next)
{

    if ($this->auth->check()) {
        if($this->auth->user()->sign_up_complete == 1){
            return redirect('/');
        } else {
            if($this->auth->user()->step_one_complete == 0){
                return redirect('/register/step-1');
            } elseif($this->auth->user()->step_two_complete == 0){
                return redirect('/register/step-2');
            } else {
                return redirect('/');
            }
        }
    }

    return $next($request);
}

这不起作用,登录后用户被重定向到/home。我尝试将dd($this->auth->user())置于$this->auth->check()条件中,但它永远不会运行。如果我将它放在该检查之外,那么它就会在每次请求时运行。看起来$this->auth->check()永远不会运行。

我的问题:如果不在这里,这个逻辑应该放在哪里?

我也从protected $redirectTo = '/account';控制器中删除了AuthController.php

6 个答案:

答案 0 :(得分:5)

您没有正确使用中间件。每当您登录时发送请求,这段代码就会触发。

要在登录后更改重定向位置,您可以覆盖AuthController中的redirectPath()方法。 (您可以在vendor/laravel/framework/src/Illuminate/Foundation/Auth/RedirectsUsers.php

中找到原始方法

这看起来像这样:

...

public class AuthController extends Controller {

    ...

    public function redirectPath()
    {
        if(Auth::user()->sign_up_complete == 1) {
            return '/';
        } else {
            if(Auth::user()->step_one_complete == 0) {
                return '/register/step-1';
            } elseif(Auth::user()->step_two_complete == 0) {
                return '/register/step-2';
            } else {
                return '/';
            }
        }
    }


    // The rest of the class implementation.

}

注意:我已使用Facade替代方法($this->auth())替换了Auth::方法。仅仅因为我不确定AuthController是否有auth()方法。

答案 1 :(得分:2)

我认为设置自定义中间件类以根据数据库值验证您的请求非常简单,我这样做是为了排除没有正确角色的用户。

该角色在我的用户表中定义,只允许具有管理员角色的用户访问系统。

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\MessageBag;

class RolesMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        // If a user is authenticated
        if(\Auth::user() != null)
        {
            // If the user doesn't have the correct role
            if(\Auth::user()->role != 'administrator')
            {
                // logout the user
                \Auth::logout();

                // create a new MessageBag
                $messageBag = new MessageBag;

                // add a message
                $messageBag->add('not_allowed', 'You are not allowed to login, because you do not have the right role!');

                // redirect back to the previous page with errors
                return \Redirect::to('login')->withErrors($messageBag);
            }
        }

        return $next($request);

    }
}

答案 2 :(得分:2)

解决方案是Mark Walet的回答,但需要稍加修正。返回应该是一个字符串:

public class AuthController extends Controller {

    ...

    public function redirectPath()
    {
        if(Auth::user()->sign_up_complete == 1) {
            return '/';
        } else {
            if(Auth::user()->step_one_complete == 0) {
                return '/register/step-1';
            } elseif(Auth::user()->step_two_complete == 0) {
                return '/register/step-2';
            } else {
                return '/';
            }
        }
    }


    // The rest of the class implementation.

}

答案 3 :(得分:2)

高级答案:RedirectIfAuthenticated的目的是防止已经通过身份验证的用户访问登录或注册路由/视图,因为他们已经登录。

测试:将登录视图添加为书签。然后登录。关闭浏览器或窗口。打开登录书签。您将直接去用户家或RedirectIfAuthenticated中指定的地方。

出于LoginController的目的,创建一个redirecTo()方法,该方法就是redirectPath()方法的作用,以查看是否已自定义重定向。

// example
public function redirectTo()
{
    switch (auth()->user()->role) {
        case 'foo':
            return route('foo.home');

        case 'bar':
            return route('bar.home');

        default:
            auth()->logout();
            return route('web.welcome');
    }
}

答案 4 :(得分:0)

你不能改变laravel的核心文件你需要做的就是添加这个代码 Auth \ AuthController

protected $redirectPath = '/dashboard';

答案 5 :(得分:0)

要了解从未到达路由逻辑的原因,您应该查看注册了RedirectIfAuthenticated中间件的app/Http/Kernel.php

protected $routeMiddleware = [
    ...
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    ...
];

这意味着如果用户导航到不受guest路由中间件保护的路由,则请求永远不会通过RedirectIfAuthenticated类,因此完全错过了您的逻辑。

您可以将访客中间件添加到路径文件中的注册路由,以强制路由通过您的代码,如下所示:

Route::get('/register/step-1', '<YOUR CONTROLLER METHOD>')->middleware('guest');

但是,既然您说用户已经登录(而不是访客),您应该按照其他答案的建议移动您的代码。

仅将此作为答案添加,因为无法在评论允许的空间内澄清。