はじめに
Laravel8から標準のユーザー認証機能がlaravel/uiからLaravel Jetstream + Laravel Fortifyに変更されました。新しい認証機能もlaravel/uiと同様に導入自体は非常に簡単で、かつ多機能(プロフィール管理、チーム管理、二段階認証などなど)、必要に応じてconfigファイルで利用する機能を選択することが可能です。その一方で認証処理の実装が変わっていることもあり、拡張するには少し手間がかかります(ました)。ドキュメントでは下記のように言及されていますが、
Laravel Jetstreamが用意する認証スカフォールドを使う必要はないことに留意してください。このスカフォールドを使用しない選択をした場合、Laravelの認証クラスを直接使用し、ユーザーの認証管理を行う必要があります。
せっかくならば新しい認証機能使いたいぞ!
ということで、本記事では一般ユーザーと管理者ユーザーでログイン画面、ログイン後の画面を分けるマルチログインをLaravel JetstreamとLaravel Fortifyを使って実装していきます。
なお、Laravel Fortifyの詳しい処理を深く追ったり説明したり、ということはこの記事ではしません。
動作環境
本記事では全てローカルで動作させます
- PHP 7.4.11
- MySQL 8.0.21
- Laravel Framework 8.10.0
マルチログインの仕様
- 一般ユーザー(User)、管理者(Admin)でログインユーザーとページを分ける
- ルーティングは以下とする(本記事ではドメインはlocalhost:8000として扱います)
- 一般ユーザーログインページ
- localhost:8000/login
- 一般ユーザートップページ
- localhost:8000/dashboard
- 管理者ログインページ
- localhost:8000/admin/login
- 管理者トップページ
- localhost:8000/admin/dashboard
- 一般ユーザーログインページ
- 両ユーザー共に未ログインの時にはトップページを表示することはできない(ログインページにリダイレクトさせる)
プロジェクトの準備
- プロジェクトの生成(今回はmulti-authというプロジェクトにしています)
- Blade + livewireを使用するので
Which Jetstream stack do you prefer?
は0を選択 - teamsは使用しないので
Will your application use teams?
はnoを選択
- Blade + livewireを使用するので
$ laravel new multi-auth --jet
| | |
|,---.|--- ,---.|--- ,---.,---.,---.,-.-.
||---'| `---.| | |---',---|| | |
`---'`---'`---'`---'`---'` `---'`---^` ' '
Which Jetstream stack do you prefer?
[0] livewire
[1] inertia
> 0
Will your application use teams? (yes/no) [no]:
> no
Installing laravel/laravel (v8.1.0)
- Installing laravel/laravel (v8.1.0): Downloading (100%)
Created project in /{your-workspace-root}/multi-auth
~~省略~~
Application ready! Build something amazing.
- プロジェクトが生成されたらアセットのビルドを実行
$ cd multi-auth
$ npm install && npm run dev
- .envのDB_DATABASEと同じ名前のDBを、ローカルのMySQLで作成してmigrationを実行
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=multi_auth ← これ
DB_USERNAME=root
DB_PASSWORD=
$ php artisan migrate
Migration table created successfully.
Migrating: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_000000_create_users_table (42.86ms)
Migrating: 2014_10_12_100000_create_password_resets_table
Migrated: 2014_10_12_100000_create_password_resets_table (19.50ms)
Migrating: 2014_10_12_200000_add_two_factor_columns_to_users_table
Migrated: 2014_10_12_200000_add_two_factor_columns_to_users_table (22.99ms)
Migrating: 2019_08_19_000000_create_failed_jobs_table
Migrated: 2019_08_19_000000_create_failed_jobs_table (25.19ms)
Migrating: 2019_12_14_000001_create_personal_access_tokens_table
Migrated: 2019_12_14_000001_create_personal_access_tokens_table (39.09ms)
Migrating: 2020_10_14_073012_create_sessions_table
Migrated: 2020_10_14_073012_create_sessions_table (52.85ms)
- Adminモデルの作成とmigrationを実行
- create_users_table.phpからupメソッドの中身をコピペ
$ php artisan make:model Admin -m
Model created successfully.
Created Migration: 2020_10_14_075325_create_admins_table
~~省略~~
public function up()
{
Schema::create('admins', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->foreignId('current_team_id')->nullable();
$table->text('profile_photo_path')->nullable();
$table->timestamps();
});
}
$ php artisan migrate
Migrating: 2020_10_14_075325_create_admins_table
Migrated: 2020_10_14_075325_create_admins_table (31.63ms)
- Adminモデルの内容を修正(User.phpからコピペ)
<?php
namespace App\Models;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Fortify\TwoFactorAuthenticatable;
use Laravel\Jetstream\HasProfilePhoto;
use Laravel\Sanctum\HasApiTokens;
class Admin extends Authenticatable
{
use HasApiTokens;
use HasFactory;
use HasProfilePhoto;
use Notifiable;
use TwoFactorAuthenticatable;
/**
* 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',
'two_factor_recovery_codes',
'two_factor_secret',
];
/**
* The attributes that should be cast to native types.
*
* @var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
/**
* The accessors to append to the model's array form.
*
* @var array
*/
protected $appends = [
'profile_photo_url',
];
}
- 一般ユーザーと管理者をシーダーで生成できるようにする
$ php artisan make:seeder UserSeeder
Seeder created successfully.
$ php artisan make:seeder AdminSeeder
Seeder created successfully.
<?php
namespace Database\Seeders;
use App\Models\User;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class UserSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
User::create([
'name' => '一般ユーザー',
'email' => 'user@user.user',
'password' => Hash::make('password'),
]);
}
}
<?php
namespace Database\Seeders;
use App\Models\Admin;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\Hash;
class AdminSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
Admin::create([
'name' => '管理者',
'email' => 'admin@admin.admin',
'password' => Hash::make('password')
]);
}
}
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class DatabaseSeeder extends Seeder
{
/**
* Seed the application's database.
*
* @return void
*/
public function run()
{
$this->call(UserSeeder::class);
$this->call(AdminSeeder::class);
}
}
$ php artisan db:seed
Seeding: Database\Seeders\UserSeeder
Seeded: Database\Seeders\UserSeeder (250.64ms)
Seeding: Database\Seeders\AdminSeeder
Seeded: Database\Seeders\AdminSeeder (106.95ms)
Database seeding completed successfully.
- ビルトインサーバーを起動してブラウザでlocalhost:8000を表示
- localhost:8000/loginにて一般ユーザーでログインできるか確認
$ php artisan serve
Starting Laravel development server: http://127.0.0.1:8000
[Mon Oct 1 00:00:00 0000] PHP 7.4.11 Development Server (http://127.0.0.1:8000) started
無事ログインできれば準備編は終了
実装編に続きます