Laravel 8.X 認証機能の調査

Laravel 8.Xで開発をするため、認証周りを調べてみました。以前5.1で開発した経験がありますが、Frameworkとして機能がかなり変わりましたので、今回調べた内容を参考として残します。
認証機能はLaravelの公式パッケージである「Jetstream」を利用しましたが、実現方法を「Livewire + Blade」と「Inertia + Vue」の中で選べられました。LivewireもInertiaもわりっと新しいライブラリのようで、MVC思考になれているLaravel利用者には使いやすくなっているようですね。
Googleログインを実現する際には、Socialiteというパッケージを利用し、Outh2で実現しました。

Jetstream

以下はJetstreamの公式サイトです。インストール手順はここを参考しました。

Inertia + Vue

「Livewire + Blade」と「Inertia + Vue」の中で何を選ぶか迷いましたが、筆者はvue.jsを勉強したかったので「Inertia + Vue」を選びました。PHPになれていて、派手なSPAを制作する予定では無ければ、CRMのような業務システムは「Livewire + Blade」の方がよさそうでした。以下はLivewireとInertiaを調査した時の参考サイトです。

Inertia + Vueで実装されたJetstreamを理解する際には、以下のサイトが参考になりました。

以下はInertiaについて調べた内容の参考先です。

上記のサイトのチュートリアルの通りに実装してみて、何となくわかるようになりました。一点注意事項は、ブラウザーでURLに接続しても実装内容が反映されなくエラーになった場合は、「npm run dev && php artisan optimize」コマンドを実行してみてください。筆者はこれで解決できました。詳細は以下の記事をご参照ください。

Tailwind CSS

Jetstreamは認証関連の画面とプロファイル設定画面表示機能も含まれています。画面を表示される際に利用しているフロントエンド側のライブラリには「tailwindcss」を利用しています。

以下は、サンプルとして参考できるサイトです。

以下はTailwind css+vue.jsで開発する際に参考となるサイトです。

Socialite

以下はLaravel公式サイトのSocialite章です。インストール手順やサンプルコードはここを参考しました。

Laravel公式サイトのサンプルコードだけでは、Google認証の流れが理解できませんでいたので、以下のサイトを参考しました。

上記のサイトを参考して、Google認証を追加しても結局Jetstreamでユーザーを登録する時のようにうまく動作しなかったです。原因はGoogle認証後ユーザーを追加する際にクエリビルダーを利用してユーザーを直接SQLで追加したからでした。Jetstreamでユーザーを追加する時と違いがあるようですね。

ソースコードを調べたところ、ユーザーの登録やログイン処理は、Jetstreamの裏処理でFortifyというLaravelの公式パッケージを利用していました。Google認証後ユーザーを追加する処理はFortifyのソースコードを見て真似して作成したところうまく動きました。

Routing

Route::get('/login/google', [GoogleController::class, 'redirect']);
Route::get('/login/google/callback', [GoogleController::class, 'callback']);

Controller

class GoogleController extends LoginController
{
    public function redirect()
    {
        return Socialite::driver('google')->redirect();
    }

    public function callback(StatefulGuard $guard, CreatesNewUsers $creator)
    {
        $google_user = Socialite::driver('google')->stateless()->user();

        if (!empty($google_email = $google_user->getEmail())) {
            if (empty($user = User::firstWhere('email', $google_email))) {
                $password = Hash::make(Str::random());
                event(new Registered($user = $creator->create([
                    'name' => $google_user->getName(),
                    'email' => $google_email,
                    'password' => $password,
                    'password_confirmation' => $password,
                    'terms' => false
                ])));
            }
            $guard->login($user);
            return app(RegisterResponse::class);
        } else {
            abort(400, '\'Google login\' failed.');
        }
    }
}