2020/7/8追記
この記事はLaravel 5.5 でやや古いです。
最新版(Laravel 8.x)を使って設定した内容をUdemy講座にしていますので、
ぜひご参考にされてください。
以下 Laravel 5.5 実施時の情報になります。
インターネット上で写真や情報をやりとりできるような
『Webアプリ』や『Webサービス』では、
使う人(ユーザー)がログインして、
自分専用の管理画面から記事を投稿したり、写真をアップできるようになっています。
PHPのてんこもりフレームワーク『Laravel(ララベル)』では、
使う人(ユーザー)がログインだけの機能であれば、
ものの1分でつくる事ができるようになっています。
Larvel5.8までなら、
php artisan make:auth
Laravel6.x 以降なら『laravel/ui』インストール必要なので、
// Laravel 最新 composer require laravel/ui --dev php artisan ui bootstrap --auth // Laravel 6.x composer require laravel/ui "1.x" --dev php artisan ui bootstrap --auth
という魔法のコマンドをうつだけ。
一方、
使う人(ユーザー)の管理画面とは別に、
設定する側(管理側・管理者)の管理画面も欲しい!っとなると、
ちょっとややこしい設定が必要になってきます。
今回はそんなマルチログイン機能についてまとめてみました。
Laravel 5.5で実施しました、Laravel8.x はUdemy講座を参照ください。
Laravelでマルチログイン機能 変更必要なファイル群
今回は、
- 使う人用 user
- 管理側 admin
の2つの管理画面をつくる事を想定しています。
アドレス(URL)は、
- 使う人用 user
ログイン画面 /login
管理画面 /home
- 管理側 admin
ログイン画面 /admin/login
管理画面 /admin/home
としています。
2つの管理画面の作り方がわかれば、あとは応用で、
3つでも4つでも管理画面を分けることができるようになります。
変更必要なファイル群はこれらです。
- create_admins_table.php (マイグレーション)
- Admin.php (モデル)
- config/auth.php (認証設定ファイル)
- app/Exceptions/Handler.php (ログインしてない時の挙動)
- route/web.php (ルーティング)
- HomeController.php (コントローラー)
- LoginController.php (コントローラー)
- views/admin/login.blade.php (ビュー)
- views/admin/home.blade.php (ビュー)
- views/layout/app_admin.blade.php (ビュー(レイアウト))
頑張ってコツコツやっていけば1時間もあればできると思うので、
ぜひレッツトライ!
Laravelでマルチログイン機能 下準備
何はともあれ『Laravel』プロジェクト作成をば。
PHPライブラリをもりっと管理できる『composer』がインストールされている状態で、
composer create-project --prefer-dist laravel/laravel "5.5.*" auth-test
で auth-test プロジェクト (フォルダ) が作成されます。
参考記事
cd auth-test
で プロジェクトフォルダに移動したらおもむろに、
php artisan make:auth
php artisan migrate
とうって、
使う人用(user)側のログイン関連のファイルはあっさり作成されます。
Laravelでマルチログイン機能 データベース周り
php artisan make:model Admin -m
とコマンドを打つ事で、
App¥Admin.php ファイル (モデルファイル)と、
create_admins_table.php ファイル (マイグレーションファイル)が生成されます。
すでに User.php (使う側用のモデルファイル)が生成されているので、
中身をコピーしつつ、 class名を Admin に変えておきます。
//Admin.php <?php namespace App; use Illuminate\Notifications\Notifiable; use Illuminate\Foundation\Auth\User as Authenticatable; class Admin extends Authenticatable //ここを変更 { use Notifiable; /** * 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', ]; }
create_admins_table.php ファイル (マイグレーションファイル) も
create_users_table.php ファイルをコピーしつつ、
class名と upメソッドのusrsをadminsに変えます。
// create_admins_table.php <?php use Illuminate\Support\Facades\Schema; use Illuminate\Database\Schema\Blueprint; use Illuminate\Database\Migrations\Migration; class CreateAdminsTable extends Migration //ここを変更 { /** * Run the migrations. * * @return void */ 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(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('users'); } }
Laravelでマルチログイン機能 認証ファイル(auth.php)
config/auth.php (認証設定ファイル) に、admin側の設定を追加します。
// config/auth.php <?php return [ /* |-------------------------------------------------------------------------- | Authentication Defaults |-------------------------------------------------------------------------- | | This option controls the default authentication "guard" and password | reset options for your application. You may change these defaults | as required, but they're a perfect start for most applications. | */ 'defaults' => [ 'guard' => 'user', // webからuserに変更 'passwords' => 'users', ], /* |-------------------------------------------------------------------------- | Authentication Guards |-------------------------------------------------------------------------- | | Next, you may define every authentication guard for your application. | Of course, a great default configuration has been defined for you | here which uses session storage and the Eloquent user provider. | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | Supported: "session", "token" | */ 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'api' => [ 'driver' => 'token', 'provider' => 'users', ], 'user' => [ 'driver' => 'session', 'provider' => 'users', ], 'admin' => [ //追加 'driver' => 'session', //追加 'provider' => 'admins', //追加 ], ], /* |-------------------------------------------------------------------------- | User Providers |-------------------------------------------------------------------------- | | All authentication drivers have a user provider. This defines how the | users are actually retrieved out of your database or other storage | mechanisms used by this application to persist your user's data. | | If you have multiple user tables or models you may configure multiple | sources which represent each model / table. These sources may then | be assigned to any extra authentication guards you have defined. | | Supported: "database", "eloquent" | */ 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\User::class, ], 'admins' => [ //追加 'driver' => 'eloquent', //追加 'model' => App\Admin::class, //追加 ], // 'users' => [ // 'driver' => 'database', // 'table' => 'users', // ], ], /* |-------------------------------------------------------------------------- | Resetting Passwords |-------------------------------------------------------------------------- | | You may specify multiple password reset configurations if you have more | than one user table or model in the application and you want to have | separate password reset settings based on the specific user types. | | The expire time is the number of minutes that the reset token should be | considered valid. This security feature keeps tokens short-lived so | they have less time to be guessed. You may change this as needed. | */ 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, ], 'admins' => [ //追加 'provider' => 'admins', //追加 'table' => 'password_resets', //追加 'expire' => 60, //追加 ], ], ];
『Laravel』にはguards(ガード)という機能があって、
どんなログイン方法にするか(セッションにするかトークンにするかなど)、
どのデータベースの情報を見にいくか(UserテーブルかAdminテーブルかなど)、
といった設定を書くことができます。
このファイルに記載していく事で、管理画面を3つにも4つにも増やすことができます。
Laravelでマルチログイン機能 リダイレクト先の設定
app/Exceptions/Handler.php ファイルで、
ログインしていない時はどの画面を表示させるか、というのを決めることができます。
app/Exceptions/Handler.php ファイルに『unauthenticated メソッド』を書く必要があるんですが、
なぜか『Laravel5.5』からはこのメソッドが消えています。
とはいえ、
『Illuminate\Auth\AuthenticationException』ファイルには『unauthenticated メソッド』が書かれているので、
それを上書き(オーバーライド)する形で書けばOKです。
// app/Exceptions/Handler.php namespace App\Exceptions; use Exception; use Illuminate\Auth\AuthenticationException; //この追加を忘れないで use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; class Handler extends ExceptionHandler { . . /* 省略 */ . /** * 認証していない場合にガードを見てそれぞれのログインページへ飛ばず * * @param \Illuminate\Http\Request $request * @param AuthenticationException $exception * @return \Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse|\Illuminate\Http\Response */ public function unauthenticated($request, AuthenticationException $exception) { if($request->expectsJson()){ return response()->json(['message' => $exception->getMessage()], 401); } if (in_array('admin', $exception->guards())) { return redirect()->guest(route('admin.login')); } return redirect()->guest(route('login')); } }
参考記事
Laravelでマルチログイン機能 ルーティング
URLにアクセスしたときにどの処理をするかを担当するのがルーティングファイルです。
// routes/web.php <?php /* |-------------------------------------------------------------------------- | Web Routes |-------------------------------------------------------------------------- | | Here is where you can register web routes for your application. These | routes are loaded by the RouteServiceProvider within a group which | contains the "web" middleware group. Now create something great! | */ Auth::routes(); /* |-------------------------------------------------------------------------- | 1) User 認証不要 |-------------------------------------------------------------------------- */ Route::get('/', function () { return redirect('/home'); }); /* |-------------------------------------------------------------------------- | 2) User ログイン後 |-------------------------------------------------------------------------- */ Route::group(['middleware' => 'auth:user'], function() { Route::get('/home', 'HomeController@index')->name('home'); }); /* |-------------------------------------------------------------------------- | 3) Admin 認証不要 |-------------------------------------------------------------------------- */ Route::group(['prefix' => 'admin'], function() { Route::get('/', function () { return redirect('/admin/home'); }); Route::get('login', 'Admin\LoginController@showLoginForm')->name('admin.login'); Route::post('login', 'Admin\LoginController@login'); }); /* |-------------------------------------------------------------------------- | 4) Admin ログイン後 |-------------------------------------------------------------------------- */ Route::group(['prefix' => 'admin', 'middleware' => 'auth:admin'], function() { Route::post('logout', 'Admin\LoginController@logout')->name('admin.logout'); Route::get('home', 'Admin\HomeController@index')->name('admin.home'); });
- 使う人用 user
ログイン画面 /login
管理画面 /home
- 管理側 admin
ログイン画面 /admin/login
管理画面 /admin/home
というURL構成になっています。
group で設定をくくって、
- prefix ・・URLの頭につける文 ‘prefix’ => ‘admin’ なら admin/login などになる。
- ‘middleware’ => ‘auth:admin’ ・・認証していれば表示できる
といった内容を追加しています。
Laravelでマルチログイン機能 コントローラー
app/Http/Controllers/の下にAdminフォルダをつくって、
その中にLoginController.phpとHomeController.phpをコピぺします。
// app/Http/Controllers/Admin/LoginController.php <?php namespace App\Http\Controllers\Admin; // Auth→Adminに変更 use App\Http\Controllers\Controller; use Illuminate\Foundation\Auth\AuthenticatesUsers; use Illuminate\Http\Request; 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:admin')->except('logout'); //変更 } public function showLoginForm() { return view('admin.login'); //変更 } protected function guard() { return Auth::guard('admin'); //変更 } public function logout(Request $request) { Auth::guard('admin')->logout(); //変更 $request->session()->flush(); $request->session()->regenerate(); return redirect('/admin/login'); //変更 } }
// app/Http/Controllers/Admin/HomeController.php <?php namespace App\Http\Controllers\Admin; // Adminを追加 use Illuminate\Http\Request; use App\Http\Controllers\Controller; 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'); //変更 } }
Laravelでマルチログイン機能 ビュー(見た目)
resources/viewsの下にadminフォルダをつくって、
login.blade.phpとhome.blade.phpをコピぺします。
また、layoutsフォルダの下にあるapp.blade.phpをコピぺして、
app_admin.blade.phpとして保存しておきます。
layouts/app_admin.blade.phpの編集箇所
ユーザーログイン画面と区別するため背景色を変更します。
<link href="{{ asset('css/app.css') }}" rel="stylesheet"> の下に <style>body{background-color: tomato;}</style> を追加。 <li><a href="{{ route('register') }}">Register</a></li> は不要なので削除。 route(‘xxxxx’)をすべてroute(‘admin.xxxxx’)に変更。
views/admin/login.blade.phpの編集箇所
1行目の @extends('layouts.app') を @extends('layouts.app_admin') に変更。 Forgot Your Password?のリンクは不要なので、 <a class="btn btn-link" href="{{ route('password.request') }}">...</a> を削除。 route(‘xxxxx’)をすべてroute(‘admin.xxxxx’)に変更。
views/admin/home.blade.phpの編集箇所
1行目の @extends('layouts.app') を @extends('layouts.app_admin') に変更。
こんな画面になればOKです。
login (ユーザー側)
admin/login (管理側)
Laravelでマルチログイン機能 tinkerでadminユーザーをつくる
管理側からは新規登録できないようにしていますが、
それだと管理側からログインができなくなってしまうので、
『Laravel』の機能、tinker を使って、管理側用のアカウントをつくっておくといいです。
$php artisan tinker $admin = new App¥Admin; >>$admin->name = 'admin'; >>$admin->email = 'test@test.com'; >>$admin->password = bcyrpt('password123'); >>$admin->save();
注意点として、パスワードはbcrypt関数を使って暗号化しておく必要があります。
Laravelでマルチログイン機能 注意点 (経験談)
マルチログインでは、セッションやリダイレクトを使う関係で、
思うように動かない場合がままあります。
Laravelでマルチログイン機能 注意点1 セッション
使う側(ユーザー)でログインして、
ログインしたまま管理側のログイン画面に移動してログインしようとすると
うまく動かない場合があります。
おそらくですが『セッション』が残ったままになっていると思われます。
– セッション・・ ブラウザとサーバーで情報を保持する仕組み
ログアウトの時に『セッション』を破棄するような記載になっているので、
使う側(ユーザー)でログインした後に、管理側でもログインしたい場合は、
使う側(ユーザー)でログアウトしてセッションを破棄してから
管理側でログインするようにした方がよいようです。
Laravelでマルチログイン機能 注意点2 キャッシュなど消す
キャッシュや設定も情報が残っていたりするので、
うまく動かない場合はこれらのコマンドも試してみるといいかもです。
composer dump-autoload //クラス情報・マイグレーション情報などを最適化
php artisan config:cache //設定ファイルのキャッシュクリア
php artisan route:clear //ルーティング情報クリア
php artisan cache:clear //キャッシュクリア
あとはブラウザで、Shiftキー押しながらF5を押してキャッシュクリアしたり。
(Macなら Ctrl +Shift + R だったはず)
Laravelでマルチログイン機能 をつくってみて
最初にトライしたときはなかなかうまくいかなくて、
気を取り直して最初から試したらあっさり実装できたりしたので、
キャッシュやセッションなど情報が残る仕組みのおかげで、
ちょっと大変な設定かなと思いますが、
コツがわかればいくらでも管理画面がつくれるし、
つくれる『Webサービス』の幅も格段に広がると思うので、
ぜひチャレンジしてもらえればと思います。
参考サイト
Laravel5.4でマルチ認証(userとadmin)を実装する方法
『Laravel』ではこんな記事も読まれています。
1. 【Laravel】マルチログイン対応ECサイトの講座をリリースしました【Udemy】2. 【PHP/Laravel】初心者向けの動画をリリースしました【Udemy】
3. 【Laravel(PHP)】初心者向け アプリのつくり方 をリリースしました【techpit】
4. 『Carbon』でよく使うパターンをまとめてみた【Laravel向け】
5. 【Laravel(PHP)】でできる事をわかりやすく(ざっくりと)まとめてみた【用語集も兼ねて】【初心者向け】
6. 【Laravel】フロントエンドをわかりやすくまとめてみた【初心者向け】
7. 【PHP】【Laravel】CSVエクスポートの方法〜5つのポイント〜
8. 【PHP】CSVインポートの方法〜大量データもバルクインサートでバッチリ!〜【laravel】
9. 【Laravel】ダミー(テスト)データを作る方法 シーダー(seeder)とfactoryとfaker【初心者向け】
10. 【Laravel】Webアプリ環境構築の仕方【Vue.js】【初心者向け】
11. 【Laravel】と【Vue.js】のサンプル動画を見ながらさらりと解説してみる
12. 【Laravel】マルチログイン(ユーザーと管理者など)機能を設定してみた【体験談】
13. 【Laravel】フォトギャラリーを作るための画像アップロード方法【php】
14. 【Laravel】多対多テーブルを複数つくる方法【ちょっとコツがいります】
15. 【Laravel】【Slack】に通知する方法をまとめてみた【自作ファサード】
アオキのツイッターアカウント。
もしよければ、教えてください。
Udemy でも受講させていただきました。
勉強になりました。
ありがとうございます。
マルチ認証した場合のユーザ登録する方法まで参考になる資料などありますで消化。
Udemyでも返信させていただきましたが、
view側のregister周りを削除するように書いているので、
register周りをそのまま残せばユーザー登録できるはずです。