果たしてこれでいいのかという疑問と、作業ログを兼ねて。Laravel をよくわかっていないので、変なことしてるかも。指摘お待ちしています。
実現したいこと
- 1つのログイン画面で、複数テーブルを使った認証を行う
-
User
テーブルと,Admin
テーブルがあって、どちらかにあればログインできて、それぞれの画面に遷移する、みたいな。 - その上
User
テーブルとAdmin
テーブルで認証に使用するカラムが異なる -
User
テーブルがid
-
Admin
テーブルがusername
-
標準の make:auth
は使えないのかなーと思っているので、自分で作っていく。
環境
- macOS 10.12.3
- PHP 7.0
- Laravel 5.4
- MySQL
準備
プロジェクトの作成といろいろ生成
bash
$ composer create-project laravel/laravel multi-auth-sample --prefer-dist "5.4.*"
$ cd multi-auth-sample
$ php artisan make:controller LoginController
$ php artisan make:controller AdminController
$ php artisan make:controller UserController
$ php artisan make:model Admin -m # User は既存のものを使う
$ php artisan make:seeder AdminTableSeeder
$ php artisan make:seeder UserTableSeeder
$ php artisan make:middleware CheckAuthenticate
$ php artisan make:middleware CheckAdminAuthenticate
route ファイル編集
routes/web.php
<?php
// ログイン画面
Route::get('/', 'LoginController@index')->name('login.index');
Route::post('/', 'LoginController@authenticate')->name('login.login');
Route::match(['get', 'post'], 'logout', 'LoginController@logout')->name('login.logout');
// Admin画面
Route::get('admin', 'AdminController@index')->name('admin.index');
// User画面
Route::get('user', 'UserController@index')->name('user.index');
作成
Model
app/Admin.php
use Illuminate\Foundation\Auth\User as Authenticatable;
class Admin extends Authenticatable
{
//
}
Migrations
create_admins_table
public function up()
{
Schema::create('admins', function (Blueprint $table) {
$table->increments('id');
$table->timestamps();
$table->string('username')->unique();
$table->string('password');
$table->rememberToken();
});
}
Seeds
database/seeds/AdminTableSeeder.php
public function run()
{
DB::table('admins')->insert([
'username' => 'admin',
'password' => Hash::make('Passw0rd'),
'remember_token' => '',
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
}
database/seeds/UserTableSeeder.php
public function run()
{
DB::table('users')->insert([
'name' => 'user',
'email' => 'user@example.com',
'password' => Hash::make('User2017'),
'remember_token' => '',
'created_at' => Carbon::now(),
'updated_at' => Carbon::now(),
]);
}
database/seeds/DatabaseSeeder.php
public function run()
{
$this->call(AdminTableSeeder::class);
$this->call(UserTableSeeder::class);
}
View
resources/views/login.blade.php
<form action="/" method="post">
{{csrf_field()}}
<label>ID: <input type="text" name="id" id="id"></label>
<label>Password: <input type="password" name="password"> </label>
<button type="submit">Login</button>
</form>
Middleware
app/Http/Kernel.php
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
// 追加
'auth.check.admin' => \App\Http\Middleware\CheckAdminAuthenticate::class,
'auth.check.user' => \App\Http\Middleware\CheckAuthenticate::class,
// 追加ここまで
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
// 追加
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'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' => 60,
],
],
app/Http/Middleware/CheckAuthenticate.php
public function handle($request, Closure $next)
{
if (Auth::guard('web')->check() === false) {
return redirect()->route('login.index');
}
return $next($request);
}
app/Http/Middleware/CheckAdminAuthenticate.php
public function handle($request, Closure $next)
{
if (Auth::guard('admin')->check() === false) {
return redirect()->route('login.index');
}
return $next($request);
}
Controller
app/Http/Controllers/LoginController.php
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
use AuthenticatesUsers;
protected $username = 'id';
public function username()
{
return $this->username;
}
public function index()
{
return view('login');
}
public function logout(Request $request)
{
if (Auth::guard('web')->check()) {
Auth::guard('web')->logout();
}
if (Auth::guard('admin')->check()) {
Auth::guard('admin')->logout();
}
return redirect()->route('login.index');
}
public function authenticate(Request $request)
{
// User ログイン
Auth::guard('web');
$this->validateLogin($request);
$id = $request->input('id');
$password = $request->input('password');
if (Auth::attempt(['id' => $id, 'password' => $password])) {
return redirect()->route('user.index');
}
// Admin ログイン
Auth::guard('admin');
$this->username = 'username';
if (Auth::guard('admin')->attempt(['username' => $id, 'password' => $password])) {
return redirect()->route('admin.index');
}
return redirect()->back();
}
}
app/Http/Controllers/AdminController.php
class AdminController extends Controller
{
public function __construct()
{
$this->middleware('auth.check.admin');
}
public function index()
{
return 'AdminPage!';
}
}
app/Http/Controllers/UserController.php
class UserController extends Controller
{
public function __construct()
{
$this->middleware('auth.check.user');
}
public function index()
{
return 'UserPage!';
}
}
確認
bash
$ php artisan migrate --seed
$ php artisan serve
# http://localhost:8000/ へアクセス