Laravel5.3でユーザーと管理者など別々で認証させたい
はじめに
例えば何かしらのWebサービスで、サービス利用者としてのユーザーとサービス運営者としての管理者のアカウントをそれぞれ別のテーブルで管理して別々で認証させたい、という時の作業内容についてのメモ。
ユーザー認証
Laravelに用意されているスカフォールドを使う。
$ php artisan make:auth
$ php artisan migrate
users
テーブルと必要なコントローラー、ビューのファイルが作成される。以下のルーティングが追加される。
$ php artisan route:list
+--------+-----------+------------------------------+----------------------+------------------------------------------------------------------------+--------------+
| Domain | Method | URI | Name | Action | Middleware |
+--------+-----------+------------------------------+----------------------+------------------------------------------------------------------------+--------------+
| | GET|HEAD | home | | App\Http\Controllers\HomeController@index | web,auth |
| | POST | login | | App\Http\Controllers\Auth\LoginController@login | web,guest |
| | GET|HEAD | login | login | App\Http\Controllers\Auth\LoginController@showLoginForm | web,guest |
| | POST | logout | logout | App\Http\Controllers\Auth\LoginController@logout | web |
| | POST | password/email | | App\Http\Controllers\Auth\ForgotPasswordController@sendResetLinkEmail | web,guest |
| | POST | password/reset | | App\Http\Controllers\Auth\ResetPasswordController@reset | web,guest |
| | GET|HEAD | password/reset | | App\Http\Controllers\Auth\ForgotPasswordController@showLinkRequestForm | web,guest |
| | GET|HEAD | password/reset/{token} | | App\Http\Controllers\Auth\ResetPasswordController@showResetForm | web,guest |
| | POST | register | | App\Http\Controllers\Auth\RegisterController@register | web,guest |
| | GET|HEAD | register | register | App\Http\Controllers\Auth\RegisterController@showRegistrationForm | web,guest |
+--------+-----------+------------------------------+----------------------+------------------------------------------------------------------------+--------------+
管理者認証
テーブル
マイグレーションで管理者用のテーブルを作成する。
$ php artisan make:migration create_admin_users_table
今回はusers
テーブルの内容を元に作成した。
<?php
// database/migrations/yyyy_mm_dd_*_create_admin_users_table.php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAdminUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('admin_users', 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::drop('admin_users');
}
}
$ php artisan migrate
admin_users
テーブルが作成される。
モデル
App/User.php
をコピーしてApp/AdminUser.php
を作成する。クラス名以外は特に変更点なし。
設定
config/auth.php
を以下のように変更する。
<?php
return [
'defaults' => [
'guard' => 'user',
'passwords' => 'users',
],
'guards' => [
'user' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admin_users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'admin_users' => [
'driver' => 'eloquent',
'model' => App\AdminUser::class,
],
],
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
'admin_users' => [
'provider' => 'admin_users',
'table' => 'password_resets',
'expire' => 60,
],
],
];
ルーティング
routes/web.php
に以下のルーティングを追加する。
Route::group(['prefix' => 'admin'], function() {
$this->get('login', 'Admin\Auth\LoginController@showLoginForm');
$this->post('login', 'Admin\Auth\LoginController@login');
$this->post('logout', 'Admin\Auth\LoginController@logout');
Route::get('/home', 'Admin\HomeController@index');
});
コントローラー
app/Http/Controllers/Auth/LoginController.php
をapp/Http/Controllers/Admin/Auth/LoginController.php
にコピーして以下のように変更する。
<?php
namespace App\Http\Controllers\Admin\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/admin/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest', ['except' => 'logout']);
}
/**
* Show the application's login form.
*
* @return \Illuminate\Http\Response
*/
public function showLoginForm()
{
return view('admin.auth.login');
}
/**
* Get the guard to be used during authentication.
*
* @return \Illuminate\Contracts\Auth\StatefulGuard
*/
protected function guard()
{
return Auth::guard('admin');
}
}
app/Http/Controllers/HomeController.php
をapp/Http/Controllers/Admin/HomeController.php
にコピーして以下のように変更する。
<?php
namespace App\Http\Controllers\Admin;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
class HomeController 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.home');
}
}
ビュー
resources/views/auth/login.blade.php
をresources/views/admin/auth/login.blade.php
にコピーして以下の箇所を変更する。
<form class="form-horizontal" role="form" method="POST" action="{{ url('/admin/login') }}">
resources/views/home.blade.php
をresources/views/admin/home.blade.php
にコピーする。
その他
app/Exceptions/Handler.php
のunauthenticated()
を以下のように変更する。
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
if (in_array('admin', $exception->guards())) {
return redirect()->guest('admin/login');
}
return redirect()->guest('login');
}
確認
ユーザーはブラウザから/register
にアクセスして登録する。管理者の登録画面は今回用意していないので別途作成する。
ユーザーは/login
からログインすると/home
に遷移する。未ログイン状態で/home
にアクセスすると/login
にリダイレクトする。
管理者は/admin/login
からログインすると/admin/home
に遷移する。未ログイン状態で/admin/home
にアクセスすると/admin/login
にリダイレクトする。
ユーザーは管理者のログイン画面からはログインできず、管理者もユーザーのログイン画面からはログインできない。