web-dev-qa-db-ja.com

Laravelの組み込み認証で認証されたロジックの場合はリダイレクトしますか?

この質問は以前に行われたことがあり、私のコードは正しいと思いますが、奇妙な動作をしています。

一部のデータベース値に応じて、ログイン後にユーザーを別のルートにリダイレクトする必要があります。これを行うには、ロジックを_app/Http/Middleware/RedirectIfAuthenticated.php_のhandleメソッドに配置するだけでよいと思いました。私の方法は現在次のようになっています:

_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_を削除しました。

10
Mike

ミドルウェアを正しく使用していません。このコードは、ログイン時にリクエストを送信するたびに起動します。

ログイン後にリダイレクトの場所を変更するには、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.

}
_

注:$this->auth()メソッドをFacadeの代替(_Auth::_)に置き換えました。AuthControllerにauth()メソッドがあるかどうかわからないという理由だけで。

5
Mark Walet

高レベルの回答: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');
    }
}
6
mangonights

解決策はMarkWaletの答えにありますが、修正はほとんど必要ありません。戻り値は文字列である必要があります。

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.

}
2
Dmitry

データベース値に基づいてリクエストを検証するカスタムミドルウェアクラスを設定するのはとても簡単だと思います。これは、正しい役割を持たないユーザーを除外するために行います。

ロールはユーザーテーブルで定義されており、管理者ロールを持つユーザーのみがシステムへのアクセスを許可されています。

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
0x1ad2

laravelのコアファイルを変更することはできません。必要なのは、このコードをAuth\AuthControllerに追加することだけです。

protected $redirectPath = '/dashboard';
1
Amir Tahani

ルーティングロジックに到達しない理由を理解するには、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');

ただし、ユーザーは(ゲストではなく)すでにログインしていると言うので、代わりに他の回答で提案されているようにコードを移動する必要があります。

コメントで許可されたスペースでは明確にできなかったため、これを回答として追加するだけです。

0