Laravel Jetstream(認証) + Inertia(Vue3)環境を構築する

# はじめに

前回、[「Inertia.jsでLaravel9 + Vue3環境を手順を追って構築する」](https://qiita.com/uehatsu/items/98b258bddb961d01627a)という投稿をしました。今回はLaravel Jetstreamを使って認証までやってみたいと思います。

# 環境

- ホスト
    - MacBook Pro (16インチ, 2019)
    - macOS Monterey 12.2.1
    - Docker Desktop 4.5.0
    - PHP 8.1.3
    - Composer 2.2.7
- ゲスト
    - Laravel Sail
    - Laravel 9.1.1
    - PHP 8.1.3
    - node.js 16.4.0
    - MySQL 8.0.x

:::note info
開発環境にはLaravel Sailを用いています
実行コマンドはLaravel Sailで実行する事を想定していますので、利用しない場合は適宜読み替えてください
:::

# 構築

## 1. Laravelプロジェクトの作成

composerでcreate-projectします。Laravel-CLIが好きな方はそちらで。

```terminal
composer create-project laravel/laravel laravel-jetstream-sample
cd laravel-jetstream-sample
```

## 2. Laravel Sail

詳しくは以前の投稿（[Laravel SailでLaravel 9 (PHP8.1 + node.js 16.x) 環境をサクッと立ち上げる](https://qiita.com/uehatsu/items/63d66d7a37510c6ff1be)）をご覧ください。

今回はmysqlとmailhogを有効化したいので、以下のコマンドを実行します。

```terminal
php artisan sail:install --with mysql,mailhog
```

Laravel Sailで開発環境を起動します。

```terminal
sail up
```

## 3. Laravel Jetstream + Inertiaのインストール

```terminal
sail composer require laravel/jetstream
sail artisan jetstream:install inertia
sail npm install
sail npm run dev
sail artisan migrate
```

http://localhost/ にアクセスするとLaravelのウェルカムページと、右上にLog in, Registerのリンクが見えるはずです。Registerからアカウントを作成するとホームページに遷移します。

ログイン名のプルダウンからProfileを選択すると名前やメールアドレスの変更、二要素認証の設定などができます。

- Profile
    - 名前の変更
    - メールアドレスの変更
    - パスワードの変更
    - 二要素認証の設定
    - ブラウザーセッションの管理
    - アカウントの削除

## 4. 日本語化（スマートな方法は現時点でありません）

通常であれば、以下の方法で日本語化が可能です。

```terminal
sail composer require laravel-lang/lang --dev
cp -a vendor/laravel-lang/lang/locales/ja lang/.
mv lang/ja/ja.json lang/.
```

```php:./config/app.php
    'timezone' => 'UTC',
    // これを ↓ こう修正
    'timezone' => 'Asia/Tokyo',

    'locale' => 'en',
    // これを ↓ こう修正
    'locale' => 'ja',

    'faker_locale' => 'en_US',
    // これを ↓ こう修正
    'faker_locale' => 'ja_JP',
```

しかし、Laravel Jetstreamのフロントエンドに、LivewireではなくInertiaを用いると、この方法は利用出来ません（一部バリデーションのエラー文言などは日本語化されます）。以下のZennの記事が参考になりますが「ライブラリ入れて一発OK」ではないので、やはりスマートさに欠けます。

https://zenn.dev/yamabiko/articles/jetstream-i18n

## 5. 認証機能の設定(Laravel Fortify)

Jetstreamの認証周りはLaravel Fortifyを元に実装されているので、認証機能の設定は`config/fortify.php`で行います。色々な設定がありますが、ここでは基本的な部分だけ紹介します。

### Registrationの無効化

以下のように`config/fortify.php`の`features`を修正します。

```php:./config/fortify.php
    'features' => [
        // Features::registration(), ← コメントアウト
        Features::resetPasswords(),
        // Features::emailVerification(),
        Features::updateProfileInformation(),
        Features::updatePasswords(),
        Features::twoFactorAuthentication([
            // 'confirm' => true,
            'confirmPassword' => true,
        ]),
    ],
```

この状態で http://localhost/ にアクセスしても、Registrationのリンクが出てきません。また、Registrationのページ http://localhost/register にアクセスしても404になるため、無効化で来ていることがわかります。

### Rest Passwordの無効化

同様に以下を修正すると、ログインページ http://localhost/login にアクセスしても"Forgot your password?"のリンクが消えています。同じように http://localhost/forgot-password にアクセスしても404になり、無効化できていることがわかります。

```php:./config/fortify.php
    'features' => [
        Features::registration(),
        // Features::resetPasswords(), ← コメントアウト
        // Features::emailVerification(),
        Features::updateProfileInformation(),
        Features::updatePasswords(),
        Features::twoFactorAuthentication([
            // 'confirm' => true,
            'confirmPassword' => true,
        ]),
    ],
```

### Email Verificationの有効化

まず以下のように`config/fortify.php`を修正します。

```php:./config/fortify.php
    'features' => [
        Features::registration(),
        Features::resetPasswords(),
        Features::emailVerification(), // ← コメントイン
        Features::updateProfileInformation(),
        Features::updatePasswords(),
        Features::twoFactorAuthentication([
            // 'confirm' => true,
            'confirmPassword' => true,
        ]),
    ],
```

その後で`app/Models/User.php`を修正します。

```php:./app/Models/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 User extends Authenticatable implements MustVerifyEmail // ← implements以下を追加
{
    // ...中略
}
```

この状態で、Registrationからユーザーを追加したり、ログイン後のProfileからメールアドレスを変更すると、メールアドレス宛にメールがとどき、Verificationが必須となります。今回メールはmailhogで受信しているので、 http://localhost:8025/ にアクセスすることでメールが受信・閲覧出来ます。

### Profile Information更新の無効化

以下のように設定すると、ログイン後のProfileにアクセスしても、名前とメールアドレスの更新が出来なくなります。

```php:./config/fortify.php
    'features' => [
        Features::registration(),
        Features::resetPasswords(),
        // Features::emailVerification(),
        // Features::updateProfileInformation(), ← コメントアウト
        Features::updatePasswords(),
        Features::twoFactorAuthentication([
            // 'confirm' => true,
            'confirmPassword' => true,
        ]),
    ],
```

### パスワード更新の無効化

同様に、以下のように設定すると、ログイン後のProfileにアクセスしても、パスワードの更新が出来なくなります。

```php:./config/fortify.php
    'features' => [
        Features::registration(),
        Features::resetPasswords(),
        // Features::emailVerification(),
        Features::updateProfileInformation(),
        // Features::updatePasswords(), ← コメントアウト
        Features::twoFactorAuthentication([
            // 'confirm' => true,
            'confirmPassword' => true,
        ]),
    ],
```

### 二要素認証の無効化

二要素認証をオフにしたい場合は、以下のようにします。

```php:./config/fortify.php
    'features' => [
        Features::registration(),
        Features::resetPasswords(),
        // Features::emailVerification(),
        Features::updateProfileInformation(),
        Features::updatePasswords(),
        // Features::twoFactorAuthentication([ ← コメントアウトここから
        //     // 'confirm' => true,
        //     'confirmPassword' => true,
        // ]), ← コメントアウトここまで
    ],
```

## 6 アプリケーションロゴの変更

デフォルトで薄紫色の丸になっているロゴですが、修正するには以下の３ファイルを修正します。

- ./resources/js/Jetstream/AuthenticationCardLogo.vue
- ./resources/js/Jetstream/ApplicationLogo.vue
- ./resources/js/Jetstream/ApplicationMark.vue

これらを修正した後で、以下を実行します。

```terminal
sail npm run dev
# or
sail npm run prod
```

# まとめ

今回は基本的な部分のみ触ってみました。本格的なアプリケーションを作成するにはもう少し調査が必要なようです。