[OAuth] Laravel 12 WorkOS Authkit Starter Kitがマジですごい

## WorkOS Authkit Starter Kit

先週(2025/2/24)、Laravel 12がリリースされました。[Release Notes](https://laravel.com/docs/12.x/)を確認すると、[New Application Starter Kits](https://laravel.com/docs/12.x/releases#new-application-starter-kits)という気になるセクションが...

以下、Copilotによる翻訳と共に原文を示します。

> In addition, we are introducing a WorkOS [AuthKit-powered variant](https://authkit.com/) of each starter kit, offering social authentication, passkeys, and SSO support. WorkOS offers free authentication for applications up to 1 million monthly active users.

> さらに、各スターターキットにWorkOS AuthKitを搭載したバリアントを導入し、ソーシャル認証、パスキー、およびSSOサポートを提供します。WorkOSは、月間100万のアクティブユーザーまでのアプリケーションに対して無料の認証を提供します。

> With the introduction of our new application starter kits, Laravel Breeze and Laravel Jetstream will no longer receive additional updates.

> 新しいアプリケーションスターターキットの導入に伴い、Laravel BreezeおよびLaravel Jetstreamは今後追加の更新を受け取らなくなります。

僕なりに簡潔にまとめると、これからは"WorkOS AuthKit"をソーシャル認証に使うべし、とのことのようです。

とはいえ"WorkOS AuthKit"ってなんなのさ、という感じですので早速試してみましょう。

この記事では、まずStep by StepでWorkOS Authkitを動かせるようにしたのち、簡単に詳細を説明していきます。

Starter Kitインストール後のアプリケーションは[ReiRev/laravel-12-workos](https://github.com/ReiRev/laravel-12-workos)のリポジトリにあります。

## WorkOS Authkit Starter Kitのアプリケーション作成

`laravel/installer`をアップデートしておきます。

```bash
composer global update laravel/installer
```

お好みのディレクトリで、Laravelのアプリケーションをインストールします。今回は、`laravel-12-workos`という名前にしてみました。設定は以下にしておきます。`Which authentication provider do you prefer? `で、`WorkOS`を選んでおきましょう。

```bash
$ laravel new laravel-12-workos

 ┌ Which starter kit would you like to install? ────────────────┐
 │ Vue                                                          │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which authentication provider do you prefer? ────────────────┐
 │ WorkOS (Requires WorkOS account)                             │
 └──────────────────────────────────────────────────────────────┘

 ┌ Which testing framework do you prefer? ──────────────────────┐
 │ Pest                                                         │
 └──────────────────────────────────────────────────────────────┘
```

Frontendのフレームワークはなんでもいいですが、今回は僕が好きなVueにしています。Reactを選んでも、基本的な動作は同じはずです。

ちなみにLaravel 12では、デフォルトでSQLiteがデータベースとして使用されるようになったようですね。

アプリケーションのディレクトリに入っておきます。

```bash
cd laravel-12-workos
```

## Step by Stepで挙動を確認する。

ひとまず何も設定を変更せずに、アプリケーションを立ち上げてみます。

```bash
php artisan serve
```

```bash
npm run dev
```

`localhost:8000`にアクセスすると以下のような画面が見えます。Laravel 11と比較してシンプルでかっこいいです。

![localhost:8000](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/d9af08cb-4c39-4967-8587-dbb6ac62d81d.png)

右上の"Log in"を押すと、以下のエラーが出るはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/902d9170-9275-44e8-9b8f-2ff4b210e9c3.png)

client_idが定義されていないよ、と言われていますね。OAuthではクライアント(ここではLaravelのアプリケーション)の事前設定が必要なのでした。本記事ではOAuthの詳細までは立ち入りませんが、詳しく知りたい方には[OAuth徹底入門 セキュアな認可システムを適用するための原則と実践](https://amzn.to/41Enu3K)がおすすめです。

### クライアントの設定

クライアントの設定は`.env`ファイルに設定します。`.env`ファイルを覗くと、以下のように記載されています。

```.env
WORKOS_CLIENT_ID=
WORKOS_API_KEY=
WORKOS_REDIRECT_URL="http://localhost:8000/authenticate"
```

WorkOSの機能を使うには、アカウント作成が必要です。[workos.com](https://workos.com/)でアカウントを作成し、Overviewの"Setup User Management"を選択します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/94257d8b-3b35-4d1f-8c92-626a5a6f4ee4.png)

その後、細かい設定を行なっていきますが、特にこだわりがなければcontinueを押していけば大丈夫です。"3. Integrate your application"で、`WORKOS_CLIENT_ID`と`WORKOS_API_KEY`が表示されるので、これを`.env`に書き込んでおきます。これらの値は、後から"API Keys"で確認することができます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/39ebaf66-5add-45d5-be11-75158ce4ea61.png)


```.env
WORKOS_CLIENT_ID=YOUR_CLIENT_ID
WORKOS_API_KEY=YOUR_API_KEY
WORKOS_REDIRECT_URL="http://localhost:8000/authenticate"
```

次に、"4. Add default redirect endpoint URI"に、`.env`に記載されていた`http://localhost:8000/authenticate`を記入します。もちろん本番環境では、`${APP_URL}/authenticate`としておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/4b28b7d7-362e-428c-8815-6be406a396ef.png)

最後に"Activate user mangement"をして設定完了です。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/a247e11b-44ce-4255-b41e-ddc4f4770ff7.png)

これで基本設定は完了です。再び"Log in"を押してみると、以下のようにソーシャルアカウントを使ってログインできるページが出るはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/9daf56ad-9514-41a0-b17b-8832ef9167c7.png)

今回はGitHubアカウントでSign Inしてみました。すると、"Verify your email address"という件名のタイトルのメールが"welcome@workos.dev"から飛んできますので、そこに記された数字をブラウザ側に入力することで登録が完了します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/e76360b6-3e58-4c47-9c8f-ff6b6dc0159f.png)

メールサーバーの設定などは何もしていませんが、このようにWorkOSが必要な認証処理を代替してくれるのが素晴らしいですね。

ログインが完了すると、`http://localhost:8000/dashboard`に遷移します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/ea169e8d-c139-4bd9-9bfd-ffceabc3c90c.png)

[僕のGitHubアカウント](https://github.com/ReiRev)と同じユーザー名、プロフィール写真がLaravelから参照できていることがわかります。

### データベースを確認する

ここまでで問題なくユーザー登録ができていそうなことは確認できましたが、念のためデータベースの情報がどのようになっているか確認しておきましょう。

登録したユーザーの情報をtinkerで確認します。

```php
laravel-12-workos$ php artisan tinker
Psy Shell v0.12.7 (PHP 8.3.14 — cli) by Justin Hileman
> User::first()
[!] Aliasing 'User' to 'App\Models\User' for this Tinker session.
= App\Models\User {#6008
    id: 1,
    name: "ReiRev ",
    email: "reirev2913@gmail.com",
    email_verified_at: null,
    #workos_id: "user_BRKHHKW4S01JNB2Z7YC5FD63RQ",
    #remember_token: null,
    avatar: "https://workoscdn.com/images/v1/fRf2SCxC4_05QXrhPbwKpm2aQapSVrkBMGjUbnLwldy",
    created_at: "2025-03-02 09:28:52",
    updated_at: "2025-03-02 09:28:52",
  }
```

ちゃんとユーザー登録ができていそうです。プロフィール画像は`avatar`というカラムに保存されていることがわかります。

### Log out

最後に、Log outがちゃんとできるか確認しておきます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/f76f4d3c-e093-4f95-82e2-0e137108579a.png)

Log outを押すと`https://error.workos.com/user_management/app-homepage-url-not-found`に遷移し以下のようなエラーが出ますので、設定を追加します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/8df950cb-7dd0-4cdc-96e4-5a9ba0b09f8b.png)

Redirectsの"Your app homepage"からホームページである`http://localhost:8000`を指定します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/5d994523-2d24-41b6-a744-056856cb90ac.png)

これで、ログアウト時に`http://localhost:8000`に戻るようになります。

## WorkOSの詳細

ここまで、WorkOSを用いてLaravelで簡単にソーシャル認証が実現できることがわかりました。ここからは、もう少し詳細を深掘りしてみます。

### 結局WorkOSとはなんなのか？

WorkOSは統合認証プラットフォーム (dentity-as-a-Service, IDaaS)です。すなわち、アプリケーションの認証認可の部分を使いやすいフレームワークとして提供します。

認証認可の方法・プロトコルには昔ながらのパスワード認証の他、主要なものとして[OAuth2.0](https://oauth.net/2/)、それを基盤とした[OpenID Connect](https://openid.net/foundation/)など様々なものがありますが、セキュリティに関わるこれらの機能は複雑で管理も手間がかかります。そこで、こうした機能をサービスとして提供し、アプリケーション開発の手間を減らしてくれるのがIDaaSというわけです。

WorkOSと似たサービスとして[Auth0](https://auth0.com/)が存在します。

### 認証のフロー

[How Single Sign-On works](https://workos.com/docs/sso/how-single-sign-on-works)のドキュメントが十分にわかりやすいと思いますので、リンクを添付するにとどめたいと思います。

### stagingとproductionについて

WorkOSのDashboardからは、stagingとproductionが選択できます。アカウント登録時点では、stagingが選択されていると思います。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2544442/a82c7c0d-9ae3-40e0-a3ea-893244ad3942.png)

名前から分かる通り、staging環境はテスト用に、production環境はデプロイ用に使用するよう記載されています。機能的にどう違いがあるのか記述を見つけられませんでしたが、そのようにした方が良いのでしょう。

production環境を使用するには、クレジットカードの登録が必要になります。

冒頭のLaravelのRelease Notesに書かれている通り、月間100万のユーザーまでは無料で使用することができます。それを超える場合、2,500 USDの月額料金がかかります。2,500 USDというのはかなりの額ですが、中規模のアプリケーションで月間100万のユーザーを超えることはなかなかないと思うので、個人的にはお得なのではないかと思います。また、[WorkOS vs. Auth0](https://workos.com/compare/auth0)では、競合サービスのAuth0に対してWorkOSの方が総合的に低コストであると主張されています。

## Laravel側の詳細

[GitHubのリポジトリ](https://github.com/ReiRev/laravel-12-workos)にWorkOS Authkit Starter Kitのコードを移しました。

[routes/auth.php](https://github.com/ReiRev/laravel-12-workos/blob/main/routes/auth.php)がWorkOSとの連携部分を理解するのに重要な部分です。

```php
Route::get('login', function (AuthKitLoginRequest $request) {
    return $request->redirect();
})->middleware(['guest'])->name('login');
```

引数の型である`AuthKitLoginRequest`等は、[laravel/workos](https://github.com/laravel/workos)パッケージに実装があります。

例えば、[AuthKitLoginRequest class](https://github.com/laravel/workos/blob/main/src/Http/Requests/AuthKitLoginRequest.php)以下のようになっています。

OAuthのstateを作成している部分があり、OAuthの仕様と照らし合わせることでどのような実装の詳細を把握することができそうです。

```php
class AuthKitLoginRequest extends FormRequest
{
    /**
     * Redirect the user to WorkOS for authentication.
     */
    public function redirect(): Response
    {
        WorkOS::configure();

        $url = (new UserManagement)->getAuthorizationUrl(
            config('services.workos.redirect_url'),
            ['state' => $state = Str::random(20)],
            'authkit',
        );

        $this->session()->put('state', $state);

        return class_exists(Inertia::class)
            ? Inertia::location($url)
            : redirect($url);
    }
}
```

## まとめ

本記事では、Laravel 12のStarter Kitで新しく導入されたWorkOSの動かし方と簡単な説明を記しました。Starter Kitを用いることで手軽にソーシャルログインが実装できるの素晴らしいと思います。皆さんのご参考になれば幸いです。