• カスタム JWT
  • JWT クレーム
  • 認可
  • 認証
  • OAuth 2.0
  • Logto

Logto を使用して JWT アクセストークンにカスタムクレームを追加し、認可を強化する

この記事では、Logto のカスタム JWT クレーム機能を使用して、認可の柔軟性とサービスプロバイダーのパフォーマンスを向上させる方法を実例を通じて紹介します。

Darcy Ye
Darcy Ye
Developer

以前の記事で、ますます多くのシステムがユーザー認証とアクセス制御のために JWT 形式のアクセストークンを使用していることに触れました。これには、JWT がユーザーの役割や権限など、役立つ情報を含めることができるという重要な理由があります。この情報は、サーバーとクライアント間でユーザーの身元情報を伝達するのに役立ち、ユーザー認証とアクセス制御を実現できます。

通常、JWT に含まれる情報は認証サーバーによって決定されます。OAuth 2.0 プロトコルによれば、JWT には通常、sub(主体)、aud(受信者)、および exp(有効期限)といったフィールドが含まれており、これらは一般に「クレーム」と呼ばれます。これらのクレームは、アクセストークンの有効性を検証するのに役立ちます。

しかし、JWT が検証に使用される場面は無数であり、一般的な JWT クレームではユーザーのニーズを満たせない場合が多いです。JWT が情報を含めることができるのであれば、より簡単に認可を行うための追加情報を含めることができないか、と考えることはよくあります。

結論としては、はい、JWT にカスタムクレームを追加することができます。たとえば、現在のユーザーのスコープやサブスクリプションレベルを追加できます。これにより、クライアントとサーバー(ここでは異なるサービスを提供するサーバー、つまりサービスプロバイダー)間でユーザーの身元情報をやり取りし、ユーザー認証とアクセス制御を実現できます。

標準的な JWT クレームについては RFC7519 を参照してください。Logto は認証と認可の両方をサポートするアイデンティティソリューションとして、これに基づいてリソースおよびスコープのクレームを拡張し、標準の RBAC をサポートしています。Logto の RBAC 実装は標準的ですが、すべてのユースケースに適合するほどシンプルで柔軟ではありません。

これに基づいて、Logto は JWT クレームのカスタマイズ機能を新たに提供し、ユーザーが追加の JWT クレームをカスタマイズできるようにし、ユーザー認証とアクセス制御がより柔軟に実施できるようにしました。

Logto のカスタム JWT クレームはどのように機能するのか?

サイドバーの「JWT クレーム」ボタンをクリックして「カスタム JWT リスティングページ」にアクセスできます。

custom-jwt-listing-page

エンドユーザー向けにカスタムクレームを追加することから始めましょう。

左側のエディターで getCustomJwtClaims 関数をカスタマイズできます。このメソッドには、tokendata、そして envVariables の 3 つの入力パラメータがあります。

  • token は、現在のエンドユーザーの資格情報とシステム構成に基づいて Logto から取得された未処理のアクセストークンペイロードであり、ユーザーのアクセスに関連する情報を含んでいます。
  • data は Logto 内のユーザーに関するすべての情報を含んでおり、ユーザーの役割、ソーシャルサインインアイデンティティ、SSO アイデンティティ、組織メンバーシップなどが含まれています。
  • envVariables は、Logto 内で現在のエンドユーザーアクセストークンの使用シナリオに対して構成した環境変数であり、必要な外部 API の API キーなどが含まれます。
details-page-user-data

右側のカードは展開でき、対応するパラメータの紹介を表示でき、そのシナリオに対して環境変数を設定することもできます。

details-page-user-test

右側のすべてのカードの紹介を読んだ後、テストモードに切り替えることができ、テストデータを編集し、左側のコードエディタで記述したスクリプトの動作が期待される結果を満たしているかどうか確認するために、編集したテストデータを使用することができます。

これは、エンドユーザーが Logto への認証リクエストを開始し、最終的に Logto から返される JWT 形式のアクセストークンを取得する際の getCustomJwtClaims 関数の実行プロセスを示すシーケンス図です。

カスタム JWT 機能が有効でない場合、図のステップ 3 はスキップされ、ステップ 2 が終了した直後にステップ 4 が実行されます。このとき、Logto は getCustomJwtClaims の戻り値を空のオブジェクトであるとみなし、その後の手順を続行します。

カスタム JWT クレームを使用して認可を強化する: 実践的な例

前のセクションでは、Logto のカスタム JWT の動作原理について説明しました。この部分では、Logto のカスタム JWT クレームを使用して、認可の柔軟性とサービスプロバイダーのパフォーマンスをどのように向上させるか、実例を通じてお見せします。

シナリオの設定

ジョンのチームは、ユーザーが AI ロボットと会話することでさまざまなサービスを受けられる AI Assistant アプリを開発しました。

AI ロボットサービスは無料および有料サービスに分かれています。無料サービスには特別な航空運賃の推薦が含まれ、有料サービスには株式予測が含まれます。

AI Assistant アプリは Logto を使用してすべてのユーザーを管理しており、ユーザーは無料ユーザー、前払いユーザー、およびプレミアムユーザーの 3 種類に分けられています。無料ユーザーは無料サービスのみを利用でき、前払いユーザーはすべてのサービスを利用でき(利用に応じて課金される)、プレミアムユーザーはすべてのサービスを利用できます(ただし、悪意のある使用を防止するためのレート制限がある)。

さらに、AI Assistant アプリは Stripe を使用してユーザーの支払いを管理しており、ユーザーの操作ログを記録する独自のログサービスを持っています。

Logto 設定

まず、AI Assistant アプリのサービス用に API リソースを作成し、recommend:flightpredict:stock の 2 つのスコープを作成します。

ai-assistant-app-resource

次に、2 つの rolesfree-user および paid-user を作成し、対応するスコープを割り当てます。

  • recommend:flight スコープを free-user ロールに割り当てます。
  • recommend:flightpredict:stock の両方のスコープを paid-user ロールに割り当てます。
free-user-role
paid-user-role

最後に、3 人のユーザー、free-userprepaid-user および premium-user を作成し、対応する役割を割り当てます。

  • ユーザー free-userfree-user ロールを割り当てます。
  • ユーザー prepaid-user および premium-userpaid-user ロールを割り当てます。
assign-free-user-role
assign-paid-user-role

以下の図に示すように、上記のシナリオで必要な認可情報を実装するために、JWT に現在ログインしているユーザーの rolesbalance、および numOfCallsToday 情報を含めることを希望しています。AI Assistant アプリでアクセストークンを検証する際に、これらの情報を使用して許可の検証を迅速に行うことができます。

test-custom-jwt-claims

envVariables を設定した後、getCustomJwtClaims 関数を実装し、「テスト実行」ボタンをクリックして、現在のテストデータに基づいた追加の JWT クレームの結果を確認します。

data.user.roles に関するテストデータが構成されていないため、結果に表示される roles は空の配列です。

カスタム JWT 機能が有効かどうかの確認

上記の Logto 設定に従ってテストで対応する結果が得られました。次に、Logto が提供するサンプルアプリを使用して、カスタム JWT が有効かどうかを検証します。Logto SDKs でお馴染みの SDK を見つけ、ドキュメントおよび対応する GitHub リポジトリに従ってサンプルアプリをデプロイします。

上記の設定に基づき、React SDK を例に取ると、LogtoConfig に対応する設定を更新する必要があります:

サンプルアプリで free_user ユーザーをサインインした後、JWT アクセストークンのペイロード部分を確認することで、rolesbalancenumOfCallsTodayisPaidUser および isPremiumUser の情報を確認できます。

sample-app-access-token-preview-free

balancenumOfCallsTodayisPaidUser および isPremiumUser の値は前回のテスト結果と一致し、roles["free-user"] です。これは、実際のエンドユーザーログインプロセスでは、ユーザーのすべてのアクセス可能なデータを取得し、それに応じて処理を行うためです。

sample-app-access-token-preview-premium

プレミアムユーザーの場合、roles["paid-user"] であり、isPaidUserisPremiumUser の両方が true になっていることがわかります。

サービスプロバイダーの認可ロジックを更新する

前のステップで、ビジネスニーズに基づいてユーザーアクセストークンにカスタムクレームを追加しました。次に、これらのクレームを使用して許可検証を迅速に実行できます。

ここでは、Logto が API 側で JWT アクセストークンの検証を行うロジックを提供します。完全なコード実装は GitHub リポジトリ で確認できます:

Logto API のアクセストークン検証ロジックを参考にして、自社のビジネスロジックに応じてカスタマイズすることができます。たとえば、ここで説明した AI Assistant アプリのシナリオでは、verifyBearerTokenFromRequest 関数内で、rolesbalancenumOfCallsTodayisPaidUserisPremiumUser などのカスタムクレームの検証ロジックを追加できます。

上記の例は、エンドユーザーのログインと JWT アクセストークンの取得に影響を与えるシナリオです。あなたのユースケースがマシン間 (M2M) の場合にも、M2M アプリのためにカスタム JWT クレームを個別に構成することができます。

ユーザー用にカスタム JWT を構成しても、M2M アプリがアクセストークンを取得する際の結果には影響しませんし、その逆も同様です。

M2M 接続の汎用性のため、Logto は現在、M2M アプリの getCustomJwtClaims メソッドで Logto 内部データを受け取る機能を提供していません。他の観点では、M2M アプリのカスタム JWT の構成方法はユーザーアプリと同じです。この記事では詳しく述べませんので、Logto のカスタム JWT 機能を利用して始めてみてください。

なぜカスタム JWT クレームを使用するのか?

ジョンの AI Assistant アプリシナリオや、Logto のカスタム JWT 機能を使用してより柔軟な認可検証を行う方法をご紹介しました。このプロセスでは、カスタム JWT 機能の利点が明らかになりました:

  1. カスタム JWT 機能を使わない場合、ユーザーは許可を確認するたびに外部 API(getCustomJwtClaims で行うことと同様)をリクエストする必要があります。この API を提供するサービスプロバイダーにとっては、追加の負担が増えるかもしれません。カスタム JWT 機能を使えば、これらの情報を直接 JWT に入れて、外部 API の頻繁な呼び出しを減らすことができます。
  2. サービスプロバイダーにとって、カスタム JWT 機能はユーザーの許可をより迅速に確認するのに役立ちます。特にクライアントがサービスプロバイダーを頻繁に呼び出す場合、サービスのパフォーマンスを向上させます。
  3. カスタム JWT 機能は、ビジネスに必要な追加の許可情報を迅速に実装するのに役立ちます。また、JWT は自己完結しており、暗号化も可能なため、改ざんされにくく、これらの情報をクライアントとサービスプロバイダー間で安全にやり取りすることができます。

また、ユーザーが Logto にアクセス トークンを発行するたびに getCustomJwtClaims が実行されるため、あまりにも複雑なロジックや帯域幅に多くを要求する外部 API リクエストを実行するのは避ける必要があります。そうでないと、サインイン プロセス中に getCustomJwtClaims の結果を待つ時間が長くなりすぎる可能性があります。getCustomJwtClaims が空のオブジェクトを返す場合、この構成項目を実際に使用する必要があるまで一時的に削除することを強くお勧めします。

結論

この記事では、Logto が基本的な JWT アクセストークンを拡張し、追加の JWT クレームの機能を拡張して、ユーザーがビジネスニーズに応じて追加のエンドユーザー情報を JWT アクセストークンに入れることができるようにし、ユーザーがログインした後にユーザーの権限を迅速に確認できるようにしました。

ジョンの AI Assistant アプリのシナリオを提供し、Logto のカスタム JWT 機能を使用して柔軟な認可検証を行う方法を示しました。また、カスタム JWT を使用する際のいくつかの重要なポイントも指摘しました。実際のビジネスシナリオに応じて、ユーザーはビジネスのニーズに応じたさまざまなユーザー関連情報を JWT アクセストークンに入れることができるため、サービスプロバイダーはユーザーの権限を迅速に確認できます。