こんにちは、今期アニメは本当に久々の豊作で毎週のアニメ消化も忙しくしているデザイナーの奥田です。
さて、久しぶりにLaravelを使って開発を行う機会がありました。
その際に使った5.2からのデフォルトの機能であるマルチ認証をご説明したいと思います。
Table of Contents
Laravel 5.4をインストール
まずはじめにhomesteadをインストールしLaravel5.4をインストールします。
homesteadのインストール方法についてはこちらをご覧ください。
composer create-project laravel/laravel Laravel --prefer-dist
途中で以下のようなエラーが出てインストールに失敗した場合はpackagistのURLをミラーサイトに変更します。
Failed to decode response: zlib_decode(): data error Retrying with degraded mode, check https://getcomposer.org/doc/articles/troubleshooting.md#degraded-mode for more info
composer config -g repositories.packagist composer https://packagist.jp
パッケージをインストールします。
cd Laravel composer install
homestead.appにアクセスし、以下のようなエラーが出ていればアプリケーションキーを生成してください。
The only supported ciphers are AES-128-CBC and AES-256-CBC
php artisan key:generate Application key [base64:0JXtw6TheNjxE/RH4xvQ2KgpvtqdefcSr682uHWnAcCM=] set successfully.
これでLaravelの初期画面が表示されればインストール完了です。
通常のAuthの生成とadminsテーブルとAdminモデルの作成
LaravelでのMulti-Authはusersテーブルとは別に認証用のテーブルを作成し個別に認証します。
今回は「users」テーブルと管理者用の「admins」テーブルという設定で説明します。
まずはartisanから通常の認証用のファイルを生成します。
php artisan make:auth
次にadminsテーブルを作成するためのマイグレーションファイルを生成します。
php artisan make:migration create_admins_table
生成されたファイルを編集します。
// database/migrations/****_**_**_******_create_admins_table.php 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(); }); } public function down() { Schema::dropIfExists('admins'); }
マイグレーションします。
php artisan migrate Migration table not found. Migration table created successfully. Migrating: 2014_10_12_000000_create_users_table Migrated: 2014_10_12_000000_create_users_table Migrating: 2014_10_12_100000_create_password_resets_table Migrated: 2014_10_12_100000_create_password_resets_table Migrating: 2017_04_25_032759_create_admins_table Migrated: 2017_04_25_032759_create_admins_table
次にモデルを作成します。
php artisan make:model Admin
// app/Admin.php namespace App; use Illuminate\Foundation\Auth\User as Authenticatable; class Admin extends Authenticatable { /** * 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の設定とリダイレクトの設定、ルーティングの設定
次にauth.phpを以下のように編集します。
// config/auth.php ... 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], 'user' => [ 'driver' => 'session', 'provider' => 'users', ], 'admin' => [ 'driver' => 'session', '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' => 60, ], ], ...
次にauth:adminでログインが必要な際のリダイレクト先を設定します。
// app/Exceptions/Handler.php ... /** * 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); } if (in_array('admin', $exception->guards())) { // ここから return redirect()->guest('admin/login'); } // ここまで追記 return redirect()->guest(route('login')); }
次にルーティングの設定をします。
// routes/web.php Route::get('/', function () { return view('welcome'); }); Auth::routes(); Route::group(['prefix' => 'admin'], function() { Route::get('login', 'Admin\Auth\LoginController@showLoginForm')->name('admin.login'); Route::post('login', 'Admin\Auth\LoginController@login')->name('admin.login'); Route::get('logout', 'Admin\Auth\LoginController@logout')->name('admin.logout'); Route::get('register', 'Admin\Auth\RegisterController@showRegisterForm')->name('admin.register'); Route::post('register', 'Admin\Auth\RegisterController@register')->name('admin.register'); Route::get('home', 'Admin\HomeController@index')->name('admin.home'); }); Route::get('/home', 'HomeController@index');
これで通常のログインは動作しますが、admin認証は指定したコントローラーと別のビューを作成しないとまだ動作しません。
コントローラーの作成
app/Controllers/Adminを作成し、その中にapp/Controllers/Authフォルダーをコピーします。
app/Http/Controllers/Admin/Auth/LoginController.phpを編集します。
// app/Http/Controllers/Admin/Auth/LoginController.php namespace App\Http\Controllers\Admin\Auth; // \Adminを追記 use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; 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'); } public function showLoginForm() { return view('admin.auth.login'); //管理者ログインページのテンプレート } protected function guard() { return \Auth::guard('admin'); //管理者認証のguardを指定 } }
app/Http/Controllers/Admin/Auth/RegisterController.phpを編集します。
namespace App\Http\Controllers\Admin\Auth; // \Adminを追記 use App\Admin; // App\Adminに変更 use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Validator; use Illuminate\Foundation\Auth\RegistersUsers; class RegisterController extends Controller { /* |-------------------------------------------------------------------------- | Register Controller |-------------------------------------------------------------------------- | | This controller handles the registration of new users as well as their | validation and creation. By default this controller uses a trait to | provide this functionality without requiring any additional code. | */ use RegistersUsers; /** * Where to redirect users after registration. * * @var string */ protected $redirectTo = '/admin/home'; // '/admin/home'に変更 /** * Create a new controller instance. * * @return void */ public function __construct() { $this->middleware('auth:admin'); // 'auth:admin'に変更 } public function showRegisterForm() { return view('admin.auth.register'); } /** * Get a validator for an incoming registration request. * * @param array $data * @return \Illuminate\Contracts\Validation\Validator */ protected function validator(array $data) { return Validator::make($data, [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => 'required|string|min:6|confirmed', ]); } /** * Create a new user instance after a valid registration. * * @param array $data * @return User */ protected function create(array $data) { return Admin::create([ // Adminに変更 'name' => $data['name'], 'email' => $data['email'], 'password' => bcrypt($data['password']), ]); } }
以上でコントローラーの設定は完了です。(パスワードの再設定は割愛します。)
ビューの作成
必要なビューを作成します。
resources/views/adminを作成し、その中にresources/views/authフォルダーをコピーします。
resources/views/layouts/app.blade.phpをコピーしresources/views/layouts/admin.blade.phpにリネームします。
admin用のレイアウトを編集します。
今回は違いがはっきりわかるようにbodyの背景色を変更します。
//resources/views/layouts/admin.blade.php <!-- Styles --> <link href="{{ asset('css/app.css') }}" rel="stylesheet"> <style>body{background-color: #26263c;}</style>
route(‘login’) を route(‘admin.login’)に変更します。
//resources/views/layouts/admin.blade.php @if (Auth::guest()) <li><a href="{{ route('admin.login') }}">Login</a></li> <li><a href="{{ route('admin.register') }}">Register</a></li> @else <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false"> {{ Auth::user()->name }} <span class="caret"></span> </a> <ul class="dropdown-menu" role="menu"> <li> <a href="{{ route('admin.logout') }}" onclick="event.preventDefault(); document.getElementById('logout-form').submit();"> Logout </a> <form id="logout-form" action="{{ route('admin.logout') }}" method="POST" style="display: none;"> {{ csrf_field() }} </form> </li> </ul> </li> @endif
resources/views/admin/auth/login.blade.php、resources/views/admin/auth/register.blade.phpのレイアウトの指定を変更し、フォームのactionを変更します。
// resources/views/admin/auth/login.blade.php @extends('layouts.admin') ... <form class="form-horizontal" role="form" method="POST" action="{{ route('admin.login') }}"> ...
// resources/views/admin/auth/register.blade.php @extends('layouts.admin') ... <form class="form-horizontal" role="form" method="POST" action="{{ route('admin.register') }}"> ...
以下のようにログインフォームが表示され、新規追加しログインできれば完了です。
最後に
Laravel5.2以降ではデフォルトでマルチ認証が使用可能なのですが、少しだけ難しい設定が必要なため今回は記事にしてみました。
皆さんも是非参考にしてみてください。