やりたいこと

  • Laravel5.4でuserとadminの2つのログイン認証を実装する。
  • 例えばちょっとしたSNSのようなコミュニティサイトだとして、ユーザー画面での会員ログインと、会員管理などの機能を持つ管理画面への管理者ログインがそれぞれ別で必要だという想定。
  • ユーザーはusersテーブル、管理者はadminsテーブルをそれぞれ使用する。
  • 以下のようなURL構成を想定。
ユーザー向け /login  
/home ユーザー認証後のみ閲覧可(Guardする)
管理者向け /admin/login  
/admin/home 管理者認証後のみ閲覧可(Guardする)

実装方法

  1. ユーザー側はLaravel通常の方法を利用し実装
  2. adminsテーブルとAdminモデルの作成
  3. auth.phpの編集と管理者ログイン画面のリダイレクト先追加
  4. ルーティングの設定
  5. コントローラーの設定
  6. ビューの設定

1. ユーザーはLaravel通常の方法を利用し実装

php artisan make:auth と php artisan migrate を実行する。

2. adminsテーブルとAdminモデルの作成

php artisan make:migration create_admins_table を実行してマイグレーションファイルを作り、以下のように編集。(今回はusersテーブルと同じカラム構造)

php artisan migrate を実行してadminsテーブルを作成した後、 php artisan make:model Admin でAdminモデルを作り以下のように編集。(もしくはUser.phpをコピーしてクラス名だけUser⇒Adminに変更でもOK、というかそっちのほうが早い)

3. auth.phpの編集と管理者ログイン画面へのリダイレクト先追加

auth.phpにadmin関連の設定を追加する。

ユーザーのguardは最初から入っている’web’を使っても問題ないが、使用箇所でユーザー向けということが明示的に分かるように敢えてuserを追加。

管理者ログイン画面へのリダイレクト先を、/app/Exceptions/Handler.phpのunauthenticatedメソッド内に追加。in_array()の第3引数にはtrueを指定するのがベター。

4. ルーティングの設定

ユーザー・管理者でそれぞれ認証(guard)が必要なページとそうでないページを分かりやすくするため自己流でガラッと変更。

  • Auth::routes()は php artisan make:auth 実行時に自動的に追加される。
  • ユーザー・管理者の各ルートページ「/」「/admin」はそれぞれ「/home」「/admin/home」にリダイレクトするようにしている。
  • ユーザー認証が必要なページは 「’middleware’ => ‘auth:user‘」内に必要に応じて記述。
  • 管理者認証が必要なページは 「‘middleware’ => ‘auth:admin」内に必要に応じて記述。
  • 管理者アカウントはtinkerなどで別途登録することにし、registerページは設けない。

5. コントローラーの設定

/app/Http/Controllers/の下にAdminディレクトリを作成し、その中にLoginController.phpとHomeController.phpをコピーする。

Controllers
┣ Admin ←新規作成
  ┣ HomeController.php ←コピーにより新規追加&編集
  ┗ LoginController.php ←コピーにより新規追加&編集
┣ Auth
  ┣ ForgotPasswordController.php
  ┣ LoginController.php ←コピー元
  ┣ RegisterController.php
  ┗ ResetPasswordController.php
┣ Controller.php
┗ HomeController.php ←コピー元

Admin/LoginController.phpの編集

Admin/HomeController.phpの編集

※web.phpのルーティングでガードをかけているのでコンストラクタの中のガード設定(17行目)は不要だが念のため記述。

6. ビューの設定

/resources/viewsの下にadminディレクトリを作成し、login.blade.phpとhome.blade.phpをコピー。さらに、layoutsディレクトリの下にあるapp.blade.phpをコピーしapp_admin.blade.phpとして同階層に配置。

views
┣ admin ←新規作成
  ┣ login.blade.php ←コピーにより新規追加&編集
  ┗ home.blade.php ←コピーにより新規追加&編集

┣ auth
  ┣ passwords
  ┣ login.blade.php ←コピー元
  ┗ register.blade.php
┣ layouts
  ┣ app.blade.php ←コピー元
  ┗ app_admin.blade.php ←コピーにより新規追加&編集

┣ home.blade.php ←コピー元
┗ welcome.blade.php

layouts/app_admin.blade.phpの編集箇所

  • ユーザーログイン画面と区別するため背景色を変更。
    <link href="{{ asset('css/app.css') }}" rel="stylesheet"> の下に <style>body{background-color: tomato;}</style> を追加。
  • <li><a href="{{ route('register') }}">Register</a></li> は不要なので削除。
  • route(‘xxxxx’)をすべてroute(‘admin.xxxxx’)に変更。

views/admin/login.blade.phpの編集箇所

  • 1行目の @extends('layouts.app') を @extends('layouts.app_admin') に変更。
  • Forgot Your Password?のリンクは不要なので、 <a class="btn btn-link" href="{{ route('password.request') }}">...</a> を削除。
  • route(‘xxxxx’)をすべてroute(‘admin.xxxxx’)に変更。

views/admin/home.blade.phpの編集箇所

  • 1行目の @extends('layouts.app') を @extends('layouts.app_admin') に変更。

以上でマルチ認証の実装が完了。

動作確認

ユーザーログイン画面

multicap1

管理者ログイン画面

multicap2

ユーザーはRegisterからアカウント登録、管理者はtinkerでアカウントを作成し、ログイン→ログアウトや未ログイン状態でホームにアクセスできないこと(ちゃんとガードが効いていること)などが確認できればOK。

ちなみにtinkerでのアカウント作成は以下のようにできる。

$ php artisan tinker
>>> App\Admin::create([‘name’ => ‘admin’, ‘email’ => ‘test@example.com’, ‘password’ => bcrypt(‘password123’)]);

参考にしたサイト

感想

Qiita風に書いてみたので疲れました。。