ユーザ用ツール

サイト用ツール


サイドバー

プログラム言語:php:laravel:認証:laravel7でマルチ認証

【Laravel 7】マルチ認証(User と Admin で階層分け)

パッケージのインストール

composer require laravel/ui:^2.4

php artisan ui vue --auth

# vue.js を使わない場合は、以下の手順は不要
# NodeJS がない場合はインストール
curl -sL https://rpm.nodesource.com/setup_14.x | bash -
yum -y install nodejs

# package.json に記載されたパッケージのインストール
npm install

# css、js ファイルのビルド(未圧縮)
npm run dev

# css、js ファイルのビルド(圧縮)
npm run production

マイグレーション

以下コマンドで、マイグレーションファイルとモデルファイルを作成。

# Model ファイル作成 (-m オプションでマイグレーションも作成)
php artisan make:model Models/Admin -m

database\migrations に作成された「create_admins_table.php」に「create_users_table.php」の中身をコピペし、admin 用に書き換える。

  • クラス名:CreateUsersTable → CreateAdminsTable
  • テーブル名:users → admins
# マイグレーションの実行
php artisan migrate

モデル

app 直下にある User.php を app\Models の中に 移動。

app\Models\User.php

// ディレクトリを移動したので、namespace を書き換え
namespace App;
 ↓
namespace App\Models;

app\Models\Admin.php

// app\Models\User.php の内容をコピペし、クラス名を書き換える
class User extends Authenticatable
 ↓
class Admin extends Authenticatable

モデルファイルのパスが変わったので、関係するファイルも書き換え。

app\Http\Controllers\Auth\RegisterController.php

use App\User;
 ↓
use App\Models\User;

config\auth.php

'model' => App\User::class,
 ↓
'model' => App\Models\User::class,

シーダー

ログイン用のアカウントを作成する。

# シーダー作成
php artisan make:seeder UsersTableSeeder
php artisan make:seeder AdminsTableSeeder

database\seeds\UsersTableSeeder.php

// 追加
use App\Models\User;

    public function run()
    {
        // 本番環境以外でのみアカウントを追加
        if (config('app.env') !== 'production') {
            $user = User::where('email', 'user@example.com')->first();
            if (is_null($user)) {
                $user = new User();
                $user->name = 'user';
                $user->email = 'user@example.com';
                $user->password = bcrypt('user');
                $user->save();
            }
        }
    }

database\seeds\AdminsTableSeeder.php

// 追加
use App\Models\Admin;

    public function run()
    {
        // 本番環境以外でのみアカウントを追加
        if (config('app.env') !== 'production') {
            $admin = Admin::where('email', 'admin@example.com')->first();
            if (is_null($admin)) {
                $admin = new Admin();
                $admin->name = 'admin';
                $admin->email = 'admin@example.com';
                $admin->password = bcrypt('admin');
                $admin->save();
            }
        }
    }

database\seeds\DatabaseSeeder.php

    public function run()
    {
        // 追加
        $this->call([
            AdminsTableSeeder::class,
            UsersTableSeeder::class,
        ]);
    }
# シーダーをオートローダに登録
php composer dump-autoload

# シーディング実行
php artisan db:seed

コンフィグ

認証の設定ファイルをマルチ認証対応に書き換える。

config\auth.php

    // デフォルトを user に変更
    'defaults' => [
        'guard' => 'user',
        'passwords' => 'users',
    ],

    'guards' => [
        // web → user に変更
        'user' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        // admin を追加
        'admin' => [
            'driver' => 'session',
            'provider' => 'admins',
        ],
        'api' => [
            'driver' => 'token',
            'provider' => 'users',
            'hash' => false,
        ],
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        // admins を追加
        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Models\Admin::class,
        ],
    ],

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],
        // admins を追加
        'admins' => [
            'provider' => 'admins',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],
    ],

コントローラー

app\Http\Controllers に User ディレクトリを作成し、Auth ディレクトリと HomeController.php をその中に移動。
今回、ログイン機能しか使わないため Auth 内のファイルは LoginController.php 以外を削除。

app\Http\Controllers\User\HomeController.php

// namespace を書き換え
namespace App\Http\Controllers\User;

// 追加
use App\Http\Controllers\Controller;

    public function __construct()
    {
        // 今回ルーティング側で auth 設定をしているため
        // コンストラクタでは何もしない
        // コントローラ側で auth を設定したい場合は以下のようにする
        // $this->middleware('auth:user');
    }

    public function index()
    {
        // 書き換え
        return view('user.home');
    }

app\Http\Controllers\User\Auth\LoginController.php

// namespace の書き換え
namespace App\Http\Controllers\User\Auth;

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

    public function __construct()
    {
        // 書き換え
        $this->middleware('guest:user')->except('logout');
    }

    // 以下追加
    protected function guard()
    {
        return Auth::guard('user');
    }

    public function showLoginForm()
    {
        return view('user.auth.login');
    }

    public function logout(Request $request)
    {
        Auth::guard('user')->logout();

        return $this->loggedOut($request);
    }

    public function loggedOut(Request $request)
    {
        return redirect(route('user.login'));
    }

app\Http\Controllers\User ディレクトリをコピーして Admin ディレクトリを作成。
ディレクトリ内の各ファイルに、以下の置換を行う。

  • User → Admin
  • user → admin

※ AuthenticatesUsers を AuthenticatesAdmins に置換しないように注意

ログイン後のリダイレクト先を Admin 用に書き換える

app\Http\Controllers\Admin\Auth\LoginController.php

    protected $redirectTo = RouteServiceProvider::ADMIN_HOME;

ルーティング

routes\web.php

Route::namespace('User')->prefix('user')->name('user.')->group(function(){
    Auth::routes([
        'register' => false,
        'reset'    => false,
        'verify'   => false
    ]);

    Route::middleware('auth:user')->group(function(){
        Route::get('home', 'HomeController@index')->name('home');
    });
});

Route::namespace('Admin')->prefix('admin')->name('admin.')->group(function(){
    Auth::routes([
        'register' => false,
        'reset'    => false,
        'verify'   => false
    ]);

    Route::middleware('auth:admin')->group(function(){
        Route::get('home', 'HomeController@index')->name('home');
    });
});

その他書き換え

app\Providers\RouteServiceProvider.php

    // 書き換え
    public const HOME = '/user/home';
    // 追加
    public const ADMIN_HOME = '/admin/home';

app\Http\Middleware\Authenticate.php

// 追加
use Illuminate\Support\Facades\Route;

    protected function redirectTo($request)
    {
        // 書き換え
        if (! $request->expectsJson()) {
            if (Route::is('user.*')) {
                return route('user.login');

            } elseif (Route::is('admin.*')) {
                return route('admin.login');
            }
        }
    }

app\Http\Middleware\RedirectIfAuthenticated.php

    public function handle($request, Closure $next, $guard = null)
    {
        // 書き換え
        if (Auth::guard($guard)->check() && $guard === 'user') {
            return redirect(RouteServiceProvider::HOME);
        } elseif (Auth::guard($guard)->check() && $guard === 'admin') {
            return redirect(RouteServiceProvider::ADMIN_HOME);
        }
        return $next($request);
    }

app\Exceptions\Handler.php

// 追加
use Illuminate\Session\TokenMismatchException;

    public function render($request, Throwable $exception)
    {
        // 追加
        // 419 csrf トークン切れで戻る
        if ($exception instanceof TokenMismatchException) {
            return back()->withErrors(['time_out' => 'セッションがタイムアウトしました']);
        }

        return parent::render($request, $exception);
    }

ビュー

views\layouts にある app.blade.php を app_user.blade.php などにリネーム。

resources\views\layouts\app_user.blade.php

// リンク先などを必要に応じて変更
route('login')
 ↓
route('user.login')

route('logout')
 ↓
route('user.logout')

app_user.blade.php をコピーして app_admin.blade.php を作成。
リンク先を route('admin.login') など admin 用に変更。

resources\views 直下に user ディレクトリ作成し、auth ディレクトリと home.blade.php を移動。
home.blade.php で extends しているファイルを変更。

resources\views\user\home.blade.php

// 書き換え
@extends('layouts.app_user')

auth ディレクトリ内にある login.blade.php 以外を削除する。

resources\views\user\auth\login.blade.php

// 書き換え
@extends('layouts.app_user')

// リンク先を変更
route('login')
 ↓
route('user.login')

resources\views\user をコピーして admin ディレクトリを作成。
admin ディレクトリ内の各ファイルについて、以下の置換を行う。

  • user → admin

一通り作業が完了したので、user、admin それぞれの URL にアクセスしてログイン画面が表示されることを確認。
https://example.com/user/home
https://example.com/admin/home

コメント

コメントを入力. Wiki文法が有効です:
 
プログラム言語/php/laravel/認証/laravel7でマルチ認証.txt · 最終更新: 2021/12/16 18:27 by humolife