以前このブログでは「Laravel初心者講座」というシリーズを連載?していたのですが、あの頃はまだLaravel4でした。
しばらく扱っていなかった間にLaravel5になり、すっかり垢抜けて進化してしまいました。
今回、仕事でちょっとしたログイン絡みのシステム構築の機会があったので、久しぶりにLaravelネタを投下してみます。
管理者とユーザのログイン窓口が別で、それぞれ管理したい。よくあるパターンですね。
Laravel5の標準のログイン認証パッケージはよくできているのですが、多少面倒なステップを踏む必要があります。
インストールは省略します!
インストールディレクトリの.envを編集して、DBの接続情報を入力しておきます。
DB_CONNECTION=mysql DB_HOST=MySQLのhost DB_PORT=MySQLのポート番号 DB_DATABASE=DB名 DB_USERNAME=DBユーザー名 DB_PASSWORD=DBパスワード
コマンド2行で終わります。
$ php artisan make:auth $ php artisan migrate
上記のマイグレーションが終わると、標準のUserモデルがapp/User.phpに、標準のUserテーブルがDBに生成された状態になります。
これを元に、Adminモデル/テーブルも作成していきます。
database/migrations に生成されている
yyyy_mm_dd_000000_create_users_table.php を複製して、
yyyy_mm_dd_000000_create_admins_table.php にリネームします。
中身の"users"という文字列をすべて"admins"に置き換えます。
もう一度migrateすると、adminsテーブルが追加されるはずです。
$ php artisan migrate
app/User.phpを複製して、app/Admin.phpにリネームします。
中身の"user"という文字列をすべて"admin"に置き換えます。
これで、標準のユーザモデルと、それを元に作った管理者モデルを使う準備ができました。
config/auth.phpにログイン認証関係の設定が書かれているのですが、そちらをMultiAuth向けに編集する必要があります。
<?php return [ 'defaults' => [ 'guard' => 'user', // web→userに変更 'passwords' => 'users', ], 'guards' => [ 'user' => [ // web→userに変更 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', 'hash' => false, ], // ここから追記 '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, ], // ここまで追記 ], ];
ログイン処理を司るControllerは、app/Http/Controllers/Authに展開されています。
adminは別処理にしたいので、これも複製して追加していきます。
今回、ユーザーがログインするのはトップページ(/)で、管理者は別に管理ページ(/admin)からログインする形を想定しています。
まず、app/Http/Controllers/Authと並列に、app/Http/Controllers/Adminディレクトリを作成します。
そして、AuthディレクトリをまるごとAdminディレクトリの中に複製します。
このような構成になりました。
このままでは正しく読み込まれないので、app/Http/Controllers/Admin/Auth内の各Controllerのnamespaceを新しいパスに書き換え、さらに読み込むモデルをUserモデルから先程作っておいたAdminモデルに変更します。
<?php namespace App\Http\Controllers\Admin\Auth; // namespaceを修正 use App\Http\Controllers\Admin\Auth; // モデルを App\User から変更 use App\Http\Controllers\Controller; use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Validator; use Illuminate\Foundation\Auth\RegistersUsers; class RegisterController extends Controller { // 以下省略 ?>
この作業をすべてのAdmin/Auth以下のControllerに行います。
Controller/HomeController.phpもController/Adminに複製して、同じようにnamespaceの修正をします。 記載されているmiddlewareやviewの表記もちょこっと弄る必要があります。
<?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\Contracts\Support\Renderable */ public function index() { return view('admin.home'); } }
仕上げにルーティングの分離です。
ルーティングはroutes/web.phpで設定します。
まず、通常のユーザーログインは以下のような設定にします。
Route::get('/', function () { return view('home'); }); // 未ログイン Route::get('login', 'Auth\LoginController@showLoginForm')->name('login'); Route::post('login', 'Auth\LoginController@login')->name('login'); Route::get('register', 'Auth\RegisterController@showRegisterForm')->name('register'); Route::post('register', 'Auth\RegisterController@register')->name('register'); Route::get('password/rest', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request'); // ログイン済 Route::group(['prefix' => '', 'middleware' => 'auth'], function(){ Route::post('logout', 'Auth\LoginController@logout')->name('logout'); Route::get('/', 'HomeController@index')->name('home'); });
上記のように、middlewareにauthを指定しておくと、ログイン済みの場合のルーティングを設定できます。
prefixは、特定のパス以下のルーティングをまとめて設定するものです。
これらを利用して管理者用のルーティングも設定すればよいので、
// 管理者未ログイン Route::group(['prefix' => 'admin', 'middleware' => 'guest:admin'], function() { Route::get('login', 'Admin\Auth\LoginController@showLoginForm')->name('admin.login'); Route::post('login', 'Admin\Auth\LoginController@login')->name('admin.login'); Route::get('register', 'Admin\Auth\RegisterController@showRegisterForm')->name('admin.register'); Route::post('register', 'Admin\Auth\RegisterController@register')->name('admin.register'); Route::get('password/rest', 'Admin\Auth\ForgotPasswordController@showLinkRequestForm')->name('admin.password.request'); }); // 管理者ログイン済 Route::group(['prefix' => 'admin', 'middleware' => 'auth:admin'], function(){ Route::post('logout', 'Admin\Auth\LoginController@logout')->name('admin.logout'); Route::get('/', 'Admin\HomeController@index')->name('home'); });
こんな感じで追記すれば、完成!
Laravel5になって、作法も構成もだいぶ変わりましたが、一度掴めてくるとサクサク気持ちよく書き進められるのは4と同じですね。
特に5は今回紹介したauth認証のような標準セットが充実しているので、プログラマーにとっての導入コストは低めだと思います。
私が最初にLaravelを紹介した頃は世の中的にもまだ新参フレームワークという扱いで、これほどスタンダード化するとは思わず、今となっては感慨深いものがあります。こんなに大きくなっちゃって...!
今後もLaravelネタは定期的に投下していきたいと思っております。
https://qiita.com/sola-msr/items/65634826bcedf3ea4ca4 (sola-msr様)
https://www.tech-corgi.com/laravel5-6-multi-auth/ (株式会社CORGI様)