Laravel9環境でマルチ認証を実装する方法まとめ

今回は、Laravel 9の環境にマルチ認証を実装する方法のまとめとなります。

実装環境
Laravel version 9.3.2
httpd version 2.4.54
MySQL version 5.7
composer version 2.3.10
laravel/ui version 4.0.0

\自身のスキルを向上するには技術書で!!/

月額¥980で技術書が読み放題!!

  • ビジネススキルとマインド向上したい!!
  • 決断や行動を先送りにしてしまう方!!

Kindle Unlimitedでは30日間無料体験実施中!登録はこちら!

事前準備

まずは、laravelのプロジェクトをcomposerを利用して作成します。

$ composer create-project laravel/laravel laravel-multi-auth

以下のようにインストールが開始する。

Creating a "laravel/laravel" project at "./laravel-multi-auth"
Info from https://repo.packagist.org: #StandWithUkraine
Installing laravel/laravel (v9.3.2)
  - Downloading laravel/laravel (v9.3.2)
  - Installing laravel/laravel (v9.3.2): Extracting archive

〜〜〜〜〜〜〜
以下、省略
〜〜〜〜〜〜〜

> @php artisan vendor:publish --tag=laravel-assets --ansi --force

   INFO  No publishable resources for tag [laravel-assets].  

> @php artisan key:generate --ansi

   INFO  Application key set successfully.  

エラーが発生せず、プロジェクトの作成が完了となります。laravel-multi-auth ディレクトリに移動しておきます。

$ cd laravel-multi-auth

次に、DBを作成します。

今回は、DB名を「laravel」とします。(.env編集)

DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=13306
DB_DATABASE=laravel
DB_USERNAME=kunisura
DB_PASSWORD=xxxxxxxxx

以上で事前準備は完了です。

※ 今回はdocker上に作成したmysqlに対して操作するためポート番号はdocker上のmysqlアクセス用のポートを指定しています。

認証に必要なテーブルを作成する

認証用のテーブルを作成します。

laravelプロジェクトを作成後、最初から「create_users_table」のmigrationファイルが存在するので、migrateする前に編集します。

今回は、マルチ認証なので、「type」カラムを追加します。(0: User、1: Admin、2: Manager)のようにしようと思います。

Schema::create('users', function (Blueprint $table) {
    $table->id();
    $table->string('name');
    $table->string('email')->unique();
    $table->timestamp('email_verified_at')->nullable();
    $table->string('password');
    $table->tinyInteger('type')->default(0); // Add
    $table->rememberToken();
    $table->timestamps();
});

次に、User.phpファイルに先程追加したtypeカラムのフィールドを追加します。User.phpファイルは「app¥Models」フォルダにあります。

protected $fillable = [
    'name',
    'email',
    'password',
    'type', //Add
];

次に type属性を返す関数を作成します(User.phpの最後に追加してください)

/**
 * The attributes that should be cast to native types.
 *
 * @var array
 */
protected function type(): Attribute {
    return new Attribute(get: fn ($value) => ["user", "admin", "superadmin"][$value],);
}

最後にmigrateしてuserテーブルを作成します。

$ php artisan migrate

   INFO  Preparing database.  

  Creating migration table ............................................................................................................... 34ms DONE

   INFO  Running migrations.  

  2014_10_12_000000_create_users_table ................................................................................................... 80ms DONE
  2014_10_12_100000_create_password_resets_table ......................................................................................... 57ms DONE
  2019_08_19_000000_create_failed_jobs_table ............................................................................................. 67ms DONE
  2019_12_14_000001_create_personal_access_tokens_table ................................................................................. 114ms DONE

テーブルの作成が完了です。

実際に作成されたテーブル構造は下記の通りです。

UI側を作成する準備

認証画面を作成する前に「laravel/ui」の導入し、以下の画面のbladeファイルを作成します。

  • ログイン
  • ユーザ登録
  • パスワード忘れ
  • パスワードリセット

以下のコマンドを実行します。

$ composer require laravel/ui
$ php artisan ui bootstrap --auth
$ npm install
$ npm run dev

実行後、下記画面が表示されればOKです。

ユーザがアクセスするためのミドルウェアを作成する

次に実施するのが、ユーザアクセスを制御するためのミドルウェアの作成です。

まずは下記コマンドを実行してmiddlewareを作成します。

$ php artisan make:middleware UserAccess

   INFO  Middleware created successfully.  

app/Http/Middleware/UserAccess.php ファイルを開き、ユーザ制御を行うためにhandle関数の引数に、アクセスユーザのタイプを追加し、そのユーザタイプにマッチしている場合、リクエストを返す処理に変更します。

public function handle(Request $request, Closure $next, $userType)
{
    if(auth()->user()->type == $userType) {
        return $next($request);
    }
    return response()->json(['Permission denied']);
}

次に app/Http/Kernel.php を編集します。
ここには、route middlewareに先程追加したUserAccessクラスを追加します。

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' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,

    // Add user access middleware
    'user-access' => \App\Http\Middleware\UserAccess::class,
];

ルート設定

コア部分が完了したので、これからはクライアント再度側の実装となります。

まずは routesの設定です。(routes/web.php)
auth用のroutesを設定後、ユーザ/管理者/マネージャー用のaccess routesを追加します。

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

// Add auth routes
Auth::routes();

// Add user access routes
Route::middleware(['auth', 'user-access:0'])->group(function () {
    Route::get('/home', [HomeController::class, 'index'])->name('home');
});

// Add admin access routes
Route::middleware(['auth', 'user-access:1'])->group(function () {
    Route::get('/admin/home', [HomeController::class, 'adminHome'])->name('admin.home');
});

// Add super admin access routes
Route::middleware(['auth', 'user-access:2'])->group(function () {
    Route::get('/manager/home', [HomeController::class, 'managerHome'])->name('manager.home');
});

コントローラーの実装

認証用のContollerの実装となります。
app/Http/Controller/HomeController を作成します。

$ php artisan make:controller HomeController

次に、HomeControllerにそれぞれのユーザタイプ用の関数を作成していきます。

class HomeController extends Controller
{
    /**
     * construct
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth');
    }

    /**
     * control index page
     *
     * @return void
     */
    public function index()
    {
        return view('home');
    }

    /**
     * control admin page
     *
     * @return void
     */
    public function adminHome()
    {
        return view('admin-home');
    }

    /**
     * control manager page
     *
     * @return void
     */
    public function managerHome()
    {
        return view('manager-home');
    }
}

Bladeファイルを編集

ホーム画面のbradeファイルを編集していきます。
今回はログインに成功した場合にアラートを出力するというコードを追加します。

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row justify-content-center">
        <div class="col-md-8">
            <div class="card">
                <div class="card-header">{{ __('Dashboard') }}</div>

                <div class="card-body">
                    <!-- Add login session judge -->
                    @if(session('login-success'))
                        <div class="alert alert-success" role="alert">
                            {{ session('login-success') }}
                        </div>
                    @endif
                    @if (session('status'))
                        <div class="alert alert-success" role="alert">
                            {{ session('status') }}
                        </div>
                    @endif

                    {{ __('You are logged in!') }}
                </div>
            </div>
        </div>
    </div>
</div>
@endsection

home.blade.phpファイルを修正したら、そのファイルをコピーして「admin-home.blade.php」「manager-home.blade.php」として作成します。それぞれアクセス後のページがわかりやすいようにしておくと良いかと思います。

ログイン制御用のコントローラを修正

事前に「php artisan ui bootstrap –auth」にてAuth系のControllerが作成されています。login部分を追加します。

app/Http/Controllers/Auth/LoginController.php

middleware('guest')->except('logout');
    }

    /**
     * Get the needed authorization credentials from the request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return array
     */
    public function login(Request $request){
        $request->validate([
            'email' => 'required|email',
            'password' => 'required|min:6',
        ]);

        $credentials = $request->only('email', 'password');

        if(!auth()->attempt($credentials)) {
            return redirect()->route('login')->with('error', 'Invalid Credentials');
        }

        if (auth()->user()->type == 1) {
            return redirect()->route('admin.home');
        }

        return redirect()->route('home');
    }
}

ダミーデータの作成

ログイン用のダミーデータを作成します。

$ php artisan make:seeder UsersSeeder

シンプルにAdminユーザと一般ユーザの2つのユーザデータを作成します。

public function run()
{
    $usersData = [
        [
           'name'   =>'Admin',
           'email'  =>'admin@example.com',
           'type' => 1,
           'password' => Hash::make('12345678')
        ],
        [
           'name'       => 'User',
           'email'      => 'user@example.com',
           'type'   => 0,
           'password'   => Hash::make('12345678')
        ],
    ];
    foreach ($usersData as $key => $val) {
        User::create($val);
    }
}

作成したら下記コマンドを実行してデータをシーディングします。

$ php artisan db:seed

テーブルにデータが挿入されました。

テスト実施

npm run devを実行した状態で下記コマンドを実行する

php artisan serve

Webサーバが立ち上がるので、”http://127.0.0.1:8000/login” にアクセスします。

以下のような画面が表示されます。

seedで登録したアカウント情報を入力します。
userの情報を入力すると、user用のページへ遷移し、adminの情報を入力すると、admin用のページに遷移すると思います。

\自身のスキルを向上するには技術書で!!/

月額¥980で技術書が読み放題!!

  • ビジネススキルとマインド向上したい!!
  • 決断や行動を先送りにしてしまう方!!

Kindle Unlimitedでは30日間無料体験実施中!登録はこちら!

最後に

いかがでしたでしょうか?
今回はlaravel 9の環境におけるマルチ認証機能を簡単に実装してみました。

是非ご参考までに

タイトルとURLをコピーしました