- 秘密にして安全に保つ: 署名鍵は他の認証情報と同様に扱い、必要とするサービスにのみ共有してください。
- ペイロードに機密データを追加しない: トークンは改ざんを防ぐために署名されていますが、デコードは容易です。パフォーマンスとセキュリティを最適化するため、ペイロードに追加するクレームは必要最小限にとどめてください。
- トークンに有効期限を設定する: 技術的には、トークンはひとたび署名されると、署名鍵が変更されるか、有効期限が明示的に設定されない限り、永久に有効です。これは潜在的な問題を招くおそれがあるため、トークンを失効または取り消すための方針を用意してください。
- HTTPS を使用する: 非 HTTPS 接続でトークンを送信しないでください。そのようなリクエストは傍受され、トークンが侵害される可能性があります。
- 認可に関するすべてのユースケースを検討する: トークンが自分のサーバーで生成されたことを保証するための追加のトークン検証システムが、要件を満たすうえで必要になる場合があります。
- 保存して再利用する: アプリケーションの攻撃対象領域を広げる不要な往復通信を減らし、をから取得して保存することで、プランのトークン上限 (該当する場合) を最適化してください。新しいトークンを毎回要求するのではなく、有効期限が切れるまでは、以後の呼び出しで保存したトークンを使用してください。トークンの保存方法は、アプリケーションの特性によって異なります。一般的な方法としては、データベース (セッションの有無にかかわらず API 呼び出しを実行する必要があるアプリ向け) や HTTP セッション (対話型セッションの利用中のみ動作するアプリ向け) があります。サーバー側での保存とトークン再利用の例については、トークンの保存を参照してください。
Authorization ヘッダーにそのトークンを設定することで実装されます。そのトークンには、 のような標準的なものを使うのが望ましいです。ほとんどのプラットフォームでライブラリが利用できますし、独自に暗号処理を実装する必要もないためです。
どちらの方法でも、ユーザーから取得できる情報量は同じです。これは、login リクエストで送信される scope パラメーターで制御されます (Lock、当社の JavaScript ライブラリ、または単純なリンクを使う場合も同様です) 。scope は .signin({scope: 'openid name email'}) メソッドのパラメーターであり、最終的には login リクエストの query string の一部になります。
デフォルトでは、トークンが大きくなりすぎるのを避けるため、トークンベースの認証では scope=openid を使用します。必要な標準の Connect (OIDC) クレームは、scope の値として追加することで、トークンに含める内容を制御できます。たとえば、scope=openid name email family_name address phone_number のように指定します。詳しくは、openid.net の Standard Claims を参照してください。
トークンベースの認証とクッキーベースの認証は組み合わせて使うこともできます。Web アプリケーションと API が同じドメインから提供されている場合は、クッキーで問題なく動作するため、トークンベースの認証が不要なこともあります。必要であれば、Web アプリケーションのフローでも JWT を返します。実装方法は SDK ごとに異なります。既存のクッキーを使わずに JavaScript から API を呼び出したい場合は、トークンの送信と保存を扱うために、Web Workers または JavaScript クロージャを使ってアクセストークンを設定する必要があります。詳しくは、トークンの保存 ページの Browser in-memory scenarios セクションを参照してください。
リフレッシュトークンの使用
offline_access スコープを含めていても、Auth0 はその API に対してリフレッシュトークンを返しません。
リフレッシュトークン交換ではルールが実行されます。特別なロジックを実行するには、ルール内で context.protocol プロパティを確認します。値が oauth2-refresh-token であれば、そのルールは交換中に実行されています。
リフレッシュトークンを取得しようとする場合、 パラメーターはルールのコンテキストオブジェクトでは使用できません。audience パラメーターを追加しようとしてエラーが発生した場合は、そのトークンに設定していないことを確認してください。
context.redirect でリダイレクトしようとすると、認証フローはエラーを返します。
ルールを使ってトークンにカスタムクレームを追加している場合、そのルールが有効である限り、リフレッシュトークンの使用時に発行される新しいトークンにもカスタムクレームが含まれます。新しいトークンがカスタムクレームを自動的に継承するわけではありませんが、リフレッシュトークンフロー中にもルールが実行されるため、同じコードが実行されます。これにより、以前に認可されたアプリケーションに新しいリフレッシュトークンの取得を求めることなく、新たに発行されるトークンのカスタムクレームを追加または変更できます。
リフレッシュトークンの上限
自動テスト
- Management API でユーザーを作成します。このユーザーをテストに使用します。
- レスポンスで
user_idが返されるので、後で使えるようテスト中は保持しておく必要があります。 - テストが完了したら、Management API を使ってユーザーを削除します。テストユーザーを削除すると、リフレッシュトークンを含む関連データも削除されます。
- Management API の device credential エンドポイントを使って、ユーザーのリフレッシュトークンを一覧表示します。このエンドポイントは、蓄積されたトークン数やページネーションの使用有無にかかわらず、順不同で最大 1000 件のトークンを返します。
- DELETE メソッドを使って、それらの資格情報を削除します。
- ユーザーが 1k を超えるトークンを持っている場合は、そのユーザーのトークンがなくなるまで、一覧表示と削除を繰り返します。
有効期限付きリフレッシュトークンを設定する
offline_access が要求されると、そのユーザーに新しいリフレッシュトークンが発行されます。ユーザーが同じデバイスでログアウトして再度ログインした場合も、新しいリフレッシュトークンが発行されます。アプリケーションでリフレッシュトークンをどのように保存・使用しているかによっては、最初のログイン時に発行された古いリフレッシュトークンは不要になることがあり、両方のトークンが同じ audience で発行されている場合、アプリケーションは新しいリフレッシュトークンを使用することになる可能性が高くなります。詳しくは、トークンの保存を参照してください。
不要になったリフレッシュトークンが蓄積するのを防ぐため、リフレッシュトークンの上限によって最も古いトークンから削除されるとはいえ、リフレッシュトークンの有効期限を設定することをお勧めします。ローテーションあり、ローテーションなし (再利用可能) のどちらのリフレッシュトークンでも、非アクティブ期限または絶対有効期限を設定できます。どちらの有効期限も、アクティブに使用されていないトークンの削除に役立ち、ユーザーのトークンが蓄積するのを防ぎます。詳しくは、リフレッシュトークンの有効期限を設定するを参照してください。
JWT の検証
署名アルゴリズム
- RS256 (SHA-256 を使用する RSA 署名): 非対称アルゴリズムです。つまり、キーは 2 つあり、1 つは公開キー、もう 1 つは秘密として保持しなければならない秘密キーです。Auth0 は署名の生成に使用する秘密キーを保持し、JWT の利用者は Auth0 が提供するメタデータエンドポイントから公開キーを取得して、それを使ってJWT 署名を検証します。
- HS256 (SHA-256 を使用する HMAC): 対称アルゴリズムです。つまり、秘密として保持しなければならない秘密キーは 1 つだけで、それを 2 者間で共有します。同じキーが署名の生成と検証の両方に使われるため、キーが漏えいしないよう十分に注意する必要があります。この秘密キー (またはシークレット) は、アプリケーション () または API (Signing Secret) を登録し、HS256 署名アルゴリズムを選択したときに作成されます。
- RS256 では、秘密キーの保有者 (Auth0) のみがトークンに署名でき、公開キーを使えば誰でもそのトークンが有効かどうかを確認できます。
- RS256 では、複数の audience に対して有効なトークンをリクエストできます。
- RS256 では、秘密キーが漏えいした場合でも、新しいシークレットを使ってアプリケーションまたは API を再デプロイすることなく、キー ローテーションを実施できます (HS256 を使用している場合は再デプロイが必要です) 。
- HS256 では、シークレットキーが漏えいした場合、新しいシークレットを使って API を再デプロイする必要があります。