laravelのログイン認証にAuthenticatesUsersを使う

ログイン認証でAuthenticatesUsersトレートを利用する場合、
laravel11からlaravel/uiライブラリが必要になったようです。

# 環境
macOS Sonoma v14.5
docker desktop for mac v4.37.2
vscode

# 前提
- sailを利用してプロジェクトが作成済みであること
プロジェクト作成についてはこちらを参考にしました
https://laravel.com/docs/11.x/installation#sail-on-macos

https://laravel.com/docs/11.x/installation#sail-on-macos

## 作成済みのUsersテーブルを使ってログイン認証する場合の手順
1. ライブラリのインストール
   ```sh
   sail /usr/bin/composer require laravel/ui
   ```
2. ログイン機能を作成
   ```
   sail artisan ui bootstrap --auth
   ```
   :::note warn
   この出力に対して、yesと入力します。`no`とした場合、ログイン画面が表示されません。
   ```sh
   The [Controller.php] file already exists. 
   Do you want to replace it? (yes/no) [yes]
   ```
   :::
3. サーバー起動
   ```
   npm install && npm run dev
   ```
http://localhost/login にアクセスすると入力画面が表示されます。
## 本題
独自に作成したテーブルを使ってログイン認証させたい場合
上記の方法ではできないので少し書き換えが必要です。

### デフォルトのusersテーブルではなく違うテーブルを使いたい
config/auth.phpを変更するだけで可能です。
```diff:config/auth.php
     'defaults' => [
-        'guard' => env('AUTH_GUARD', 'web'),
+        'guard' => env('AUTH_GUARD', 'sub_user'),
         'passwords' => env('AUTH_PASSWORD_BROKER', 'users'),
    ],
...
// guards配列に追加
+        'sub_user' => [
+            'driver' => 'session',
+            'provider' => 'sub_users',
+        ],
// providers配列に追加
+        'sub_users' => [
+            'driver' => 'eloquent',
+            'model' => App\Models\SubUser::class,
+        ],
```
### デフォルトのusersテーブルも違うテーブルも使いたい
1. ログイン機能で作成した以下のファイルを複製
$this->middlewareに`config/auth.php`で定義したguards配列のキー名を設定します
ただしミドルウェア名`throttle`には設定できません[^1] 
**対象**
    - app/Http/Controllers/HomeController.php    
    - app/Http/Controllers/Auth/ConfirmPasswordController.php
    - app/Http/Controllers/Auth/LoginController.php
    - app/Http/Controllers/Auth/RegisterController.php
    - app/Http/Controllers/Auth/VerificationController.php

    ```diff
    // 例) ほかのミドルウェアにも同様にguards配列のキー名を設定
    - $this->middleware('auth');
    + $this->middleware('auth:sub_user');
    ```
2. 複製したファイルのnamespaceを変更、ファイル名を変更した場合、クラス名も変更
    ```php
    // コピー先のフォルダパスと一致させる
    namespace App\Http\Controllers\AuthCopy;
    ```
3. 複製したファイルに定義されている`$redirected`定数を新たに作成したトップ画面URLに変更する
    ```diff
    - protected $redirectTo = '/home';
    + protected $redirectTo = '/cp/home';
    ```
4. ルーティングの変更
独自に作成した場合`Route::auth()`ではnamespaceが異なるため参照できないようなので直接書く
    ```routes/web.php
    use App\Http\Controllers\AuthCopy\LoginController;
    use App\Http\Controllers\AuthCopy\RegisterController;
    // コピーしたHomeControllerのフォルダパス(namespace名)
    use App\Http\Controllers;

    Route::get('login', [LoginController::class, 'showLoginForm'])->name('login');
    Route::post('login', [LoginController::class, 'login']);
    Route::post('logout', [LoginController::class, 'logout'])->name('logout');
    Route::get('register', [RegisterController::class, 'showRegistrationForm'])->name('register');
    Route::post('register', [RegisterController::class, 'register']);
    Route::get('/cp/home', [HomeCopyController::class, 'index'])->name('home');
    ```
5. 登録データ先を変更
コピーした`RegisterController.php`の登録先データをUserクラスから独自に作成したテーブルのモデルクラスに変更
6. ガードに作成したguards配列のキー名を定義
   コピーした`LoginController.php`に関数を追加する
    ```php
    use Illuminate\Support\Facades\Auth;
    /**
     * Get the guard to be used during authentication.
     *
     * @return \Illuminate\Contracts\Auth\StatefulGuard
     */
    protected function guard()
    {
        // guards配列のキー名を設定
        return Auth::guard('sub_user');
    }
    ```
7. 画面からアクセスするとユーザー登録、ログイン・ログアウトができます。

## 補足
- `bootstrap` にはほかに`vue`, `react`も指定できるようです
詳細はhelpコマンド(`sail artisan ui --help`)を確認してください
- `Route::auth()`は laravel/ui独自の関数です[^2]
   
[^1]: ミドルウェアについて詳細はこちら
https://laravel.com/docs/12.x/middleware#middleware-aliases
[^2]: 実際の処理はこちらを参照ください
vendor/laravel/ui/src/AuthRouteMethods.php