Help us understand the problem. What is going on with this article?

【準備編】Laravel 8(+jetstream, fortify)でマルチログイン

はじめに

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を選択
$ laravel new multi-auth


    |     |         |
    |,---.|--- ,---.|--- ,---.,---.,---.,-.-.
    ||---'|    `---.|    |    |---',---|| | |
`---'`---'`---'`---'`---'`    `---'`---^` ' '


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を実行
.env
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
create_admins_table.php
~~省略~~
    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からコピペ)
Admin.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.
UserSeeder.php
<?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'),
        ]);
    }
}
AdminSeeder.php
<?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')
        ]);
    }
}
DatabaseSeeder.php
<?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

スクリーンショット 2020-10-19 14.54.04.png

スクリーンショット 2020-10-19 14.53.37.png

無事ログインできれば準備編は終了

実装編に続きます

nasteng
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away