Laravel5でマルチ認証(adminとuser)を実装します。
一般の会員制のサイトなどでは、user(ユーザー)のログインページだけでなく、admin(管理者)のログインページもあるのが一般的だと思います。
Laravel5の環境構築については、下記のリンクを参照してください。
今回は、以前の記事の続きです。下記の記事を参照して、まず、ユーザーのログイン機能を作成してください。
環境
- CentOS 7.4
- PHP 7.2.7
- MySQL 5.7.22
- Apache 2.4.6
- Laravel 5.5/5.6
今回は、ユーザーはuserテーブル、アドミンはadminテーブルを作成し、マルチログインの機能を作成していきます。
adminsテーブルとAdminモデルの作成
まず、最初にadminsテーブルとAdminモデルを作成します。
php artisan make:migration create_admins_table
Laravelのルートディレクトリで上記のコマンドをうち、マイグレーションファイルを作成します。
[root@localhost migrations]# pwd /laravel_root_directory/database/migrations
上記の場所に作成された、マイグレーションファイルを編集します。
今回は、usersテーブルと同じカラム構造のマイグレーションファイルを作成します。
<?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateAdminsTable extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('admins', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('email')->unique(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('admins'); } }
php artisan migrate を実行してadminsテーブルを作成します。
php artisan migrate
MysSQLのテーブルを見ると、adminsテーブルば作成されていることが確認できます。
mysql> show tables; +-------------------+ | Tables_in_laravel | +-------------------+ | admins | | migrations | | password_resets | | users | +-------------------+ 4 rows in set (0.00 sec)
次に、Adminモデルを作成します。Laravelのルートディレクトリで下記のコマンドを打ってください。
php artisan make:model Admin
app配下にある、Adminモデルのファイルを下記の様に編集します。Userモデルをコピーして、クラス名をUserをAdminに変更しても編集しても大丈夫です。
<?php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class Admin extends Authenticatable { use Notifiable; protected $guard = 'admin'; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', ]; /** * The attributes that should be hidden for arrays. * * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; }
auth.phpの編集adminログイン画面へのリダイレクト先追加
auth.phpにadmin関連の設定を追加します。
'defaults' => [ // webからuserに変更 'guard' => 'user', 'passwords' => 'users', ], ... 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], //ここから 'user' => [ 'driver' => 'session', 'provider' => 'users', ], 'admin' => [ 'driver' => 'session', 'provider' => 'admins', ], 'admin-api' => [ 'driver' => 'token', 'provider' => 'admins', ], //ここまでを追加 ], ... 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], //ここから 'admins' => [ 'driver' => 'eloquent', 'model' => App\Admin::class, ], //ここまでを追加 ... 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, ], //ここから 'admins' => [ 'provider' => 'admins', 'table' => 'password_resets', 'expire' => 15, ], //ここまでを追加 ],
ユーザーのguardは最初から入っている’web’を使っても問題ないですが、使用箇所でユーザー向けということが明示的に分かるようにuserへ変更しています。
App/Exceptions/Handler.phpを開き下記のように編集
App/Exceptions/Handler.phpを開き、下記の内容に書き換えます。
<?php namespace App\Exceptions; use Exception; use Illuminate\Auth\AuthenticationException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; class Handler extends ExceptionHandler { /** * A list of the exception types that should not be reported. * * @var array */ protected $dontReport = [ \Illuminate\Auth\AuthenticationException::class, \Illuminate\Auth\Access\AuthorizationException::class, \Symfony\Component\HttpKernel\Exception\HttpException::class, \Illuminate\Database\Eloquent\ModelNotFoundException::class, \Illuminate\Session\TokenMismatchException::class, \Illuminate\Validation\ValidationException::class, ]; /** * Report or log an exception. * * This is a great spot to send exceptions to Sentry, Bugsnag, etc. * * @param \Exception $exception * @return void */ public function report(Exception $exception) { parent::report($exception); } /** * Render an exception into an HTTP response. * * @param \Illuminate\Http\Request $request * @param \Exception $exception * @return \Illuminate\Http\Response */ public function render($request, Exception $exception) { return parent::render($request, $exception); } /** * Convert an authentication exception into an unauthenticated response. * * @param \Illuminate\Http\Request $request * @param \Illuminate\Auth\AuthenticationException $exception * @return \Illuminate\Http\Response */ protected function unauthenticated($request, AuthenticationException $exception) { if ($request->expectsJson()) { return response()->json(['error' => 'Unauthenticated.'], 401); } $guard = array_get($exception->guards(), 0); switch ($guard) { case 'admin': $login = 'admin.login'; break; default: $login = 'login'; break; } return redirect()->guest(route($login)); } }
app/Http/Middleware/RedirectIfAuthenticated.phpの内容を書き換える
次に、app/Http/Middleware/RedirectIfAuthenticated.phpの内容を下記の様に書き換えます。
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\Auth; class RedirectIfAuthenticated { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string|null $guard * @return mixed */ public function handle($request, Closure $next, $guard = null) { switch ($guard) { case 'admin': if (Auth::guard($guard)->check()) { return redirect()->route('admin.dashboard'); } break; default: if (Auth::guard($guard)->check()) { return redirect('/home'); } break; } return $next($request); } }
Adminコントローラを作成する
/app/Http/Controllers/AdminController.phpにコントローラを下記の様に作成します。
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; class AdminController extends Controller { /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth:admin'); } /** * Show the application dashboard. * * @return \Illuminate\Http\Response */ public function index() { return view('admin'); } }
AdminLoginControllerを作成する
php artisan make:controller auth/AdminLoginController
のartisanコマンドを打つか、下記のソースをコピーしてapp/Http/Controllers/Auth/AdminLoginController.phpを作成し、Adminログインコントローラを作成します。
<?php namespace App\Http\Controllers\Auth; use Illuminate\Http\Request; use App\Http\Controllers\Controller; use Auth; class AdminLoginController extends Controller { public function __construct() { $this->middleware('guest:admin'); } public function showLoginForm() { return view('auth.admin-login'); } public function login(Request $request) { // Validate the form data $this->validate($request, [ 'email' => 'required|email', 'password' => 'required|min:6' ]); // Attempt to log the user in if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)) { // if successful, then redirect to their intended location return redirect()->intended(route('admin.dashboard')); } // if unsuccessful, then redirect back to the login with the form data return redirect()->back()->withInput($request->only('email', 'remember')); } }
routes/web.phpの修正
routes/web.phpに下記の内容を追加します。
<?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::get('/home', 'HomeController@index')->name('home'); //ここから Route::prefix('admin')->group(function() { Route::get('/login', 'Auth\AdminLoginController@showLoginForm')->name('admin.login'); Route::post('/login', 'Auth\AdminLoginController@login')->name('admin.login.submit'); Route::get('/', 'AdminController@index')->name('admin.dashboard'); }); //ここまで
home.blade.phpをコピーして、admin.blade.phpを作成する
home.blade.phpをコピーして、admin.blade.phpを作成します。
/resources/viewsで下記コマンドを。
$ cp home.blade.php admin.blade.php
views/auth/admin-login.blade.phpの作成
views/auth/admin-login.blade.phpに下記の内容のファイルを作成します。
@extends('layouts.app') @section('content') <div class="container"> <div class="row"> <div class="col-md-8 col-md-offset-2"> <div class="panel panel-default"> <div class="panel-heading">ADMIN Login</div> <div class="panel-body"> <form class="form-horizontal" role="form" method="POST" action="{{ route('admin.login.submit') }}"> {{ csrf_field() }} <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}"> <label for="email" class="col-md-4 control-label">E-Mail Address</label> <div class="col-md-6"> <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus> @if ($errors->has('email')) <span class="help-block"> <strong>{{ $errors->first('email') }}</strong> </span> @endif </div> </div> <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}"> <label for="password" class="col-md-4 control-label">Password</label> <div class="col-md-6"> <input id="password" type="password" class="form-control" name="password" required> @if ($errors->has('password')) <span class="help-block"> <strong>{{ $errors->first('password') }}</strong> </span> @endif </div> </div> <div class="form-group"> <div class="col-md-6 col-md-offset-4"> <div class="checkbox"> <label> <input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> Remember Me </label> </div> </div> </div> <div class="form-group"> <div class="col-md-8 col-md-offset-4"> <button type="submit" class="btn btn-primary"> Login </button> <a class="btn btn-link" href="{{ route('password.request') }}"> Forgot Your Password? </a> </div> </div> </form> </div> </div> </div> </div> </div> @endsection
これで、Laravel5.5でのマルチログインは、完成です。
管理者ログインのページは、メールでのパスワードの再発行をせず、管理者がロールなどを設定して、アカウントを発行することなどが多いと思い、今回はパスワードリマインダーの機能の作成までは、していません。
また、最初のアカウントの発行は、tinkerを使用すると、簡単に認証アカウントを発行することが出来ます。
php artisan tinker
のコマンドを打つと、Laravelのプログラムを書くことが出来、普通にLaravelのソースを書くことでアカウントを発行することが出来ます。ぜひ、試してみてください。
作成したアカウントで、”http://ip-address/admin/login”にアクセスして認証をするとログインできます。
今回は、Laravel5.5の環境でマルチログインの機能を作成してみました。Laravel5.5の環境でマルチログインを実装しようとしている人の参考になると嬉しいです。