この質問は以前に行われたことがあり、私のコードは正しいと思いますが、奇妙な動作をしています。
一部のデータベース値に応じて、ログイン後にユーザーを別のルートにリダイレクトする必要があります。これを行うには、ロジックを_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
_を削除しました。
ミドルウェアを正しく使用していません。このコードは、ログイン時にリクエストを送信するたびに起動します。
ログイン後にリダイレクトの場所を変更するには、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()
メソッドがあるかどうかわからないという理由だけで。
高レベルの回答: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');
}
}
解決策は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.
}
データベース値に基づいてリクエストを検証するカスタムミドルウェアクラスを設定するのはとても簡単だと思います。これは、正しい役割を持たないユーザーを除外するために行います。
ロールはユーザーテーブルで定義されており、管理者ロールを持つユーザーのみがシステムへのアクセスを許可されています。
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);
}
}
laravelのコアファイルを変更することはできません。必要なのは、このコードをAuth\AuthControllerに追加することだけです。
protected $redirectPath = '/dashboard';
ルーティングロジックに到達しない理由を理解するには、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');
ただし、ユーザーは(ゲストではなく)すでにログインしていると言うので、代わりに他の回答で提案されているようにコードを移動する必要があります。
コメントで許可されたスペースでは明確にできなかったため、これを回答として追加するだけです。