Laravelでログイン前後の画面遷移を自由に設定してみる

テーマ

こんにちは!naoto555です。
本記事では、Laravelでログイン前後の画面遷移先を自由に設定してみる方法に関して説明していこうと思います。
更に応用として、特定のユーザーのみ入れるページを作ってみる方法も解説していこうと思いますので、是非最後までご覧ください。
(2024.2記載)

開発環境

統合開発環境 aws cloud9
PHP 8.1.17
Laravel 9.52.4
login機能 Laravel/jetstream(livewire)
Database SQlite(version 3.7.17)

Laravel/JetStream導入直後のHOME, ページ遷移

Laravel/JetStream導入直後のページ遷移図は以下のものになります。
HOME右上に、ログインページと登録ページへのリンクがありログイン後はHOMEのURL末尾に”/dashboard”を追加したダッシュボードページへと遷移します。ダッシュボードページへはログイン状態でないと入れなく、手動で”/dashboard”と直接URLを入力するとログインページに自動で飛ばされてしまいます。Laravel/JetStreamの導入に関しては、こちらの記事でまとめていますので、ご参照下さい。

ホーム画面の設定方法の解説

①Laravel導入直後のホーム画面設定

route/web.php」に記載のある、以下のコードでホームの設定を行っています。Laravelの初期設定では、ルートパス(/)にアクセスした場合に表示されるページとして、"return view('welcome');"、つまり、resources/views/welcome.blade.php というビューファイルを表示する記述がされています。

route/web.php

Route::get('/', function () {
    return view('welcome');
});

 

②ルーティングの設定方法とコントローラーでのページの表示方法

HOME画面を設定していく前に、ルーティングの設定方法とコントローラでのページの表示方法に関して簡単に解説します。ルーティングの設定方法の基本的な記述は以下に示す記述になります。

route/web.php

Route::get('/test', function () { return view('samples.test');});

 

上記のコードを「web.php」に記述することで、HOMEのURLの末尾に”/test”という入力をすると、"resources/views/samples/test.blade.php"を開くようになります。
"resources/views/samples"フォルダと"resources/views/samples/test.blade.php"ファイル、コントローラ等は以下のコマンドを用いたり、UIにて手動で作成する必要があります。

mkdir resources/views/samples
touch resources/views/samples/test.blade.php

コントローラでビューを表示するときにも同じような記述を行います。下記では、TestControllerのtest()という機能を使用したとき、"resources/views/samples/test.blade.php"を表示しなさいという記述になります。

class TestController extends Controller
{
    public function test()
    {
        return view('sample.test');
    }
}

しかし、コントローラの記述だけではURLの設定はできませんので、上記のコントローラのfunctionとURLを紐づけするために”web.php”に以下のような記述を行います。

route/web.php

use App\Http\Controllers\TestController;

//--------------------------中略--------------------------

Route::get('/test', [TestController::class, 'test'])->name('test');

 

④HOME画面(ログイン前)の設定

ログイン前のHOME画面の設定は、web.phpの以下の部分で設定されています。
それを以下のように変更すれば、HOME画面(ログイン前)が、
"resources/views/welcome.blade.php""resources/views/samples/test.blade.php"に変更されます。

route/web.php

Route::get('/', function () { return view('welcome'); });
Route::get('/', function () { return view('samples.test'); });

 

コントローラを経由して、"resources/views/samples/test.blade.php"を表示したい場合は③で紹介した手順に従い、TestControllerを作成し、以下のように記述すればよいです。

route/web.php

use App\Http\Controllers\TestController;

//--------------------------中略--------------------------

Route::get('/', [TestController::class, 'test'])->name('test');

 

⑤ログイン後の遷移先の設定

続いて、ログイン後にどの画面に遷移させるかを設定する方法について解説します。
ログイン前は先に設定した"resources/views/samples/test.blade.php"にアクセスして、ログイン後は"resources/views/products/index.blade.php"にアクセスしたい場合は以下のような記述をします。
ログイン認証後のURLは、’/product’になりますが、手入力で’product’を削除して’/’と入力しても、’/product’にリダイレクトするようになります。

ユーザー認証 URL 表示ビュー
ログイン認証前 https://……amazonaws.com resources/views/samples/test.blade.php
ログイン認証後 https://……amazonaws.com(/product) resources/views/products/index.blade.php

route/web.php

//ログイン認証前の表示ビュー
Route::middleware(['guest'])->group(function () {
    Route::get('/', function () {
        return view('samples.test');
    });
});

//ログイン認証後の表示ビュー
Route::middleware([
    'auth:sanctum',
    config('jetstream.auth_session'),
    'verified'
])->group(function () {
    Route::get('/product', function () {
        return view('products.index');
    })->name('products.index');
});

 

app/Providers/RouteServiceProvider.php

//public const HOME = '/dashboard';
public const HOME = '/product';

 

「web.php」では、ログイン前に”/”にアクセスした場合、’guest’ミドルウェアが実行されます。そして’guest’ミドルウェアが実行された後、Route::get(‘/’, function(){….})のコールバック関数が実行され、samples.testビューが表示されます。

ログイン認証後は、”app/Providers/RouteServiceProvider.php“で”/project”をHOMEに設定しているので、”/”にアクセスしたときはHOME画面に遷移します。
web.phpではログインしていない状態で、手入力で”/product”を入力した場合にログインページに飛ばす処理を行っています。

ログイン認証で使用している、各ミドルの機能は以下の通りです。

auth:sanctum
認証に必要な処理を行うミドルウェアで、Sanctumという認証パッケージを利用しています。ユーザーがログインしているかどうかを確認し、ログインしていない場合はリダイレクトしてログインページに遷移させます。

config(‘jetstream.auth_session’)
認証のためのミドルウェアです。認証が必要なリクエストで、セッションの認証が通っていない場合はログインページにリダイレクトします。

verified
ユーザーがメールアドレスの確認を済ませているかどうかを確認するためのミドルウェアです。
メール確認が済んでいない場合は、メール確認画面にリダイレクトします。(デフォルトはオフなので有効にしない限り機能しません。)

⑥特定のユーザーのみ入れるページを作ってみよう

ミドルウェアを使うことで特定のユーザーのみがアクセスできるページを作ることができます。例えば、UserのIDが3以下でないと入れないようなページを作成してみましょう。

ミドルウェアの作成
まず、以下のコマンドをターミナルに打って、UserCheckというミドルウェアを作成していきます。

# app/Http/Middleware/UserCheck.phpを作成
php artisan make:middleware UserCheck

ミドルウェアの編集
作成されたミドルウェアを、以下のように編集していきます。’/admin’にアクセス時の挙動を以下のように条件分岐させます。
・ログイン認証していないユーザーは、"resources/views/samples/test.blade.php"を表示させます。
・ログイン認証していて、ユーザーのIDが3以下のユーザーは、"resources/views/admins/admin.blade.php"を表示させます。
・ログイン認証していて、ユーザーのIDが4以上のユーザーは、"resources/views/products/index.blade.php"を表示させます。

また、ミドルウェアはリクエストを処理する段階で実行されるため、ビューを直接返すことはできません。そのため「web.php」で書いたような"return view('sample.test')"みたいな書き方はできなく、リダイレクトを使用してルートアクションを介してビューを返す必要があり、"return redirect()->route('sample.test')"と記述しています。

app/Http/Middlewere/UserCheck.php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;  //追加

class UserCheck
{   
    public function handle(Request $request, Closure $next)
    {
        //-------------------------追加(ここから)-------------------------
        if(Auth::check()){
            //ログインユーザーの情報を取得
            $user = Auth::user();
            if($user->id <= 3){
                return $next($request);
            }else{
                return redirect()->route('products.index');
            }
        }else{
            return redirect()->route('samples.test');
        }
        //-------------------------追加(ここまで)-------------------------
    }
}

 

ミドルウェアをカーネルに登録
作成したミドルウェアをカーネルに登録していきます。

app/Http/Middlewere/Kernel.php

protected $routeMiddleware = [
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
    'signed' => \App\Http\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
    'usercheck' => \App\Http\Middleware\UserCheck::class, //追加
];

 

作成したミドルウェアを使ったルーティングを設定
作成したミドルウェアをルーティングをweb.phpに登録していきます。カーネルに登録した’usercheck’を使って、Route::middleware([‘usercheck’])->group(function(){….});と記述していきます。ユーザーID=1~3なら、’/admin’とURLを直接入力したときに"resources/views/admins/admin.blade.php"にアクセスし、それ以外ならフラッシュメッセージとともに"resources/views/products/index.blade.php"にリダイレクトします。

route/web.php

//ログイン認証前の表示ビュー
Route::middleware(['guest'])->group(function () {
    Route::get('/', function () {
        return view('samples.test');
    })->name('samples.test');
});

//ログイン認証後の表示ビュー
Route::middleware([
    'auth:sanctum',
    config('jetstream.auth_session'),
    'verified'
])->group(function () {
    Route::get('/product', function () {
        return view('products.index');
    })->name('products.index');
});

//------------------------------追加(ここから)------------------------------
//特定ユーザー(IDが3以下)のみ入れるページ
Route::middleware(['usercheck'])->group(function(){
    Route::get('/admin', function () {
        return view('admins.admin');
    })->name('admins.admin');   
});
//------------------------------追加(ここまで)------------------------------

 

⑦ビューを作成して動きをみてみましょう

以下コマンドで各種ビューを作っていき、ルーティングを変更します。

#samples/testビューを作成(ログイン認証前)
mkdir resources/views/samples
touch resources/views/samples/test.blade.php

#products/indexビューを作成(ログイン認証後)
mkdir resources/views/products
touch resources/views/products/index.blade.php

#admins/adminビューを作成(特定ユーザー、IDが3以下)
mkdir resources/views/admins
touch resources/views/admins/admin.blade.php

resources/views/samples/test.blade.php

<h1>ログイン認証前のページ</h1>


resources/views/products/index.blade.php

<h1>ログイン認証後のページ</h1>

resources/views/admins/admin.blade.php

<h1>Adminページ</h1>
<p>あなたのユーザーIDは3以下です。</p>

 

各URLでの表示を表にしてみました。

権限ユーザー以外、’/admin’にはアクセスできないようになっています。
今回の例では、ユーザーのIDが3以下のユーザーのみ’/admin’にアクセスできるようになっていますが、Userテーブルにadminカラムを追加してadminカラムがtrueのときだけアクセスできるようにするなど、ミドルウェアのif文の条件を変えれば、アプリケーションにあった制限ページを作成することが可能です。

まとめ

要点をまとめると以下になります。

ログイン前のHOME設定

①「web.php」に以下を記入

Route::middleware(['guest'])->group(function(){Route::get('/',function(){...});

 

ログイン後のHOME設定

①「web.php」に以下を記入

Route::middleware([
    'auth:sanctum',
    config('jetstream.auth_session'),
    'verified'
])->group(function () {
    Route::get('/XXXX', function () {
        ....
    })->name('YYYY');
});

 

②「RouteServiceProvider.php」に以下を記載(/XXXXはHOMEに設定したいURL)

public const HOME = '/XXXX';

 

特定のユーザーのみ入れるページを作成する

①ミドルウェアを作成(XXXX:ミドルウェア名)

php artisan make:middleware XXXX

 

②作成したミドルウェアを編集(条件:ページ閲覧の条件)

if(Auth::check()){
    $user = Auth::user();
    if(条件){
        return $next($request);
    }else{
        //return redirect()->route('閲覧権限なしユーザーの遷移先');
    }
}else{
    //return redirect()->route('非ログインユーザーの遷移先');
}

 

③作成したミドルウェアを「Kernel.php」に登録(XXXX:作成したミドルウェア名, YYYY:ルーティングで呼び出すときの名前)

protected $routeMiddleware = [ 
    'YYYY' => \App\Http\Middleware\XXXX::class,
];

 

④「web.php」に作成したミドルウェアのルーティングを設定(XXXX:ミドルウェア名,YYYY:URL,ZZZZ:ビューでの名前)

Route::middleware(['XXXX'])->group(function(){
    Route::get('/YYYY', function(){....})->name('ZZZZ'); 
});