メモ > 技術 > フレームワーク: Laravel > マルチ認証(管理者とユーザで別々に認証)
マルチ認証(管理者とユーザで別々に認証)
Laravelでマルチ認証(マルチログイン)を実装する
https://leben.mobi/blog/laravel5_multi_login/php/
基本的には上記の解説を参考に作成
ただし解説どおりだと、認証エラーのメッセージが表示されなかったので以下の内容は変更している
/app/Http/Controllers/Auth/AdminLoginController.php
users テーブルに加えて admins テーブルを作成し、管理者情報を格納するものとする
モデルは /app/Entities 内に置いているものとする
■Admin用のマイグレーションとモデルを作成
php artisan make:model Admin -m
マイグレーションの内容をusersと合わせる
Schema::create('admins', function (Blueprint $table) {
$table->engine = 'InnoDB';
$table->increments('id');
$table->string('name', 85)->comment('名前');
$table->string('email', 85)->unique()->comment('メールアドレス');
$table->string('password', 60)->comment('パスワード');
$table->rememberToken();
$table->timestamps();
});
DB::statement('ALTER TABLE admins COMMENT \'管理者\'');
モデルの内容をusersと合わせる
<?php
namespace App\Entities;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
use Notifiable;
/**
* 複数代入を行う属性
*
* @var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* 配列には含めない属性
*
* @var array
*/
protected $hidden = [
'password', 'remember_token',
];
}
■マイグレーションを実行
php artisan migrate
■認証設定ファイルにAdmin用の設定を追加
/config/auth.php
<?php
return [
'defaults' => [
'guard' => 'user', // web から 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\Entities\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
// ここから追加
'admins' => [
'driver' => 'eloquent',
'model' => App\Entities\Admin::class,
],
// ここまで追加
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
// ここから追加
'admins' => [
'provider' => 'admins',
'table' => 'password_resets',
'expire' => 15,
],
// ここまで追加
],
];
■認証失敗処理を追加
/app/Exceptions/Handler.php
use Illuminate\Auth\AuthenticationException;
〜中略〜
/**
* 認証エラーがあればリダイレクト
*
* @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
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');
}
}
/app/Http/Controllers/Auth/AdminLoginController.php を作成
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Auth;
use Illuminate\Validation\ValidationException;
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'));
}
return $this->sendFailedLoginResponse($request);
}
/**
* Get the failed login response instance.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*
* @throws ValidationException
*/
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
'email' => [trans('auth.failed')],
]);
}
}
■Admin用のルーティングを追加
/routes/web.php
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');
});
■Admin用のビューを作成
resources/views/home.blade.php を複製して resources/views/admin.blade.php を作成
resources/views/auth/login.blade.php を複製して resources/views/auth/admin-login.blade.php を作成
admin-login.blade.php
<div class="panel-heading">ログイン</div>
<div class="panel-body">
<form class="form-horizontal" method="POST" action="{{ route('login') }}">
以下のように変更
<div class="panel-heading">Adminログイン</div>
<div class="panel-body">
<form class="form-horizontal" method="POST" action="{{ route('admin.login.submit') }}">
■動作確認
ユーザ情報の登録は作成していないので、usersテーブルの内容をもとに手動でadminsテーブルにユーザを登録する
http://blog.homestead.test/
http://blog.homestead.test/admin/
以下は要検証
・AdminLoginController.php の内容を再度考えたい
・web.php の「->name('admin.login.submit');」は、ユーザ側には無いので省略するか
・マイグレーションのファイル名は、最初の構築以降は日付を含めるか