https://<name>.auth.didit.me:本番環境のアプリケーションの場合https://<name>.sandbox.auth.didit.me:サンドボックスのアプリケーションの場合- または、有効化された後の独自のカスタムドメイン
DIDIT_AUTH_ISSUERには末尾のスラッシュを付けずに発行者を設定し、DIDIT_APPLICATION_IDにはアプリケーションIDを設定してください。トークンのaudにはこのIDが含まれます。公開可能キー(publishable key)には発行者がエンコードされています。pk_live_またはpk_test_に続く部分が、パディングなしのbase64urlで表した発行者です。
カスタムドメインが有効になると、デフォルトのホストに代わってそのドメインが発行者になります。新しいトークンは
issでそのドメインを示し、ディスカバリーではjwks_uriがそのドメインを指し、公開可能キーも変わります。その後、デフォルトのホストで発行されたアクセストークンは、リフレッシュされるまでGET /session/で失敗します。ドメインを有効化する際にDIDIT_AUTH_ISSUERを更新するか、古いトークンが期限切れになるまで、最大5分間、両方の発行者を受け入れてください。ディスカバリーとキー
発行者は以下をサポートしています。
- レスポンスタイプ
codeとレスポンスモードquery。 - グラントタイプ
authorization_codeとrefresh_token。 - PKCEメソッドは
S256のみ。クライアントはパブリッククライアントです。クライアントシークレットはなく、client_idはアプリケーションIDです。 - 署名アルゴリズム
ES256(P-256キー)。 - スコープ
openid、email、phone、profile、offline_access。
prompt=noneもサポートされていません。セッションの読み取りと確認にはGET /session/を使用してください。
キャッシュとローテーション
どちらのドキュメントもCache-Control: public, max-age=300を返すため、ローカルキャッシュおよび共有キャッシュで5分間保持できます。多くのバックエンドインスタンスが1つのアドレスを共有することが多いため、IPアドレスごとに1分あたり1,200リクエスト、1時間あたり12,000リクエストまで許可しており、サインインのエンドポイントを大きく上回ります。
- 各キーには
kidがあり、新しいキーIDはk_で始まります。すべてのトークンはkidヘッダーで署名に使用したキーを示します。 - キーは30日ごとにローテーションされます。Diditは次のキーを署名開始の1日前に公開し、以前のキーは署名停止後も1日間公開し続けます。そのため、5分間キャッシュしたJWKSはローテーションをまたいでも検証を続けられます。
- キーは
kidごとにキャッシュしてください。手元にないkidをトークンが示している場合はJWKSを再取得し(最大で1分に1回)、それでもキーが見つからなければトークンを拒否してください。 - 侵害されたキーをDiditが失効させると、そのキーは直ちにJWKSから削除され、
GET /session/はそのキーで署名されたすべてのトークンを拒否します。代替キーは1日前の事前公開なしで、直ちに署名を開始します。最大5分前にキャッシュされたJWKSは失効したキーをまだ受け入れ、代替キーもまだ認識していないため、キャッシュが更新されるまで新しいトークンはオフライン検証に失敗する可能性があります。
サインインの開始
authorization_endpointであるホスト型ページを開きます。
クイックスタートを使うと、このリクエストが自動で構築されます。
コードの交換
コールバックはcodeとstateを受け取ります。stateを確認してから、60秒以内にコードを交換してください。各コードは1回しか使用できません。リクエストボディはJSONとフォームエンコードのどちらでも構いません。
expires_inは、アクセストークンの残り秒数を示します。複数セッションを無効にしている場合、この交換によってその人の他のセッションは終了します。
アクセストークンのクレーム
アクセストークンは、ヘッダーがalg: ES256およびtyp: at+jwtのJWTです。有効期間は最大5分で、セッションより長くなることはありません。
IDトークンのヘッダーは
typ: JWTです。client_idを除く同じクレームに加えてauth_timeとemail_verifiedを含み、値がある場合はemail、name、phone_numberも含みます。nonceを含むのはコード交換で取得したIDトークンのみで、サインイン時にnonceが指定されていた場合に限ります。リフレッシュで取得したIDトークンには決して含まれないため、コード交換時に確認してください。IDトークンがアクセストークンとして受け入れられることはありません。
サーバーでトークンを検証する
クレームを信頼する前に、以下をすべて確認してください。algがES256、typがat+jwtであること。noneを含め、それ以外のアルゴリズムはすべて拒否してください。kidがお客様のアプリケーションのJWKSに含まれ、署名が検証されること。issが設定済みの発行者と一致し、audがお客様のアプリケーションIDと一致すること。- 最大60秒の時刻のずれを許容したうえで
expとiatが有効であり、sub、sid、jtiが存在すること。 actがnullであること。AIエージェントのアクセストークンは同じ鍵で署名され、同じtyp、iss、audを持つため、区別できるのはactだけです。エンドポイントがエージェントを受け入れる場合を除き、拒否してください。受け入れる場合は、act.scopesが付与する操作のみを許可してください。GET /session/はエージェントのトークンを常に拒否します。
GET /session/を呼び出してください。
セッションを確認する
sub、sid、application_id、vendor_data、amr、mfa_verified、email、email_verified、phone、verified_identity、verified、expires_at、post_logout_redirect_uri、organizationsが含まれます。各組織エントリにはorganization_id、organization__name、role、custom_roleがあります。
このチェックはオフライン検証よりも厳格です。セッションが無効化された、アイドル状態になった、または有効期間を超えた場合、その人物がブロックされた、またはメールアドレスが認証済みでなくなった場合、セッションがお客様のMFAポリシーを満たさなくなった場合(たとえば、その人物が認証アプリを追加した後や組織の管理者になった後)、またはトークンがリフレッシュによって置き換えられた場合にも失敗します。失敗すると、WWW-Authenticate: Bearerとともに401 {"detail": "invalid_token"}が返されます。
GET /session/では、IPアドレスごとに1分あたり30リクエスト、1時間あたり300リクエストまで許可されます。この制限はDELETE /session/と共有されます。トークンはリクエストごとにオフラインで検証し、このエンドポイントは必要な場面に限って呼び出してください。成功した呼び出しはそれぞれアクティビティとして扱われるため、セッションのidle_timeoutがリセットされます。
認証済みのメールアドレスは本人確認ではありません。本人確認についてはverifiedを参照してください。ここでは本人確認がない場合はnullになりますが、トークンでは{}になります。
リフレッシュトークン
- リフレッシュトークンはランダムな文字列で、セッションが終了するまで有効です。
- 再利用するとセッションが終了します。使用済みのリフレッシュトークンが再度届くと、Diditはそれを盗難の兆候とみなし、セッションを失効させて
400 {"error": "invalid_grant"}を返します。そのセッションのトークンも、以前のリフレッシュで発行されたものを含めて使用できなくなります。それらのリフレッシュトークンによるリフレッシュは失敗し、アクセストークンを使用したGET /session/は直ちに失敗します。ただし、有効期限が切れるまで(5分以内)はオフラインでは引き続き検証に成功します。 - タブ、デバイス、サーバーインスタンスをまたいで、1つのセッションにつきリフレッシュは一度に1つだけ実行し、3つのトークンはまとめて置き換えてください。
- リフレッシュが
400で失敗した場合や応答がない場合は、サインインをやり直してください。やみくもに再試行しないでください。実際には成功していたリフレッシュの後に再試行すると、再利用とみなされます。 503 {"error": "temporarily_unavailable"}は、リフレッシュが実行されておらず、お客様のリフレッシュトークンが引き続き使用できることを意味します。バックオフを入れて再試行してください。- Diditはリフレッシュの実行前に
429を返すため、Retry-Afterの後に再試行してください。トークンエンドポイントでは、IPアドレスごとに1分あたり30リクエスト、1時間あたり300リクエストまで許可されます。さらに、お客様のアプリケーションのすべてのPOSTとDELETEはボット対策のバケットを共有します。上限は、これらのエンドポイント全体でIPアドレスごとに1分あたり60リクエスト、デバイスごとに1分あたり30リクエスト、アプリケーション全体で1分あたり1,000リクエストで、ブラウザとサインインステップも含まれます。 - アクセストークンの有効期間が5分の場合、1時間あたり300回のリフレッシュで、アクティブな状態が続く約25人に対応できます。サーバーが1つのアドレスから多数の人物のためにリフレッシュする場合は、リクエストで新しいトークンが必要なときにのみリフレッシュし、可能な場合はブラウザやアプリでリフレッシュしてください。
サインアウト
ユーザーの現在のアクセストークンを付けてDELETE /session/を呼び出すと、セッションが終了し204が返ります。そのセッションのリフレッシュトークンは使えなくなり、そのすべてのアクセストークンは直ちにGET /session/で拒否されます。ただし、オフラインで検証するトークンは有効期限が切れるまで有効なままです。その後、post_logout_redirect_uriを設定している場合は、ユーザーをそのURLに遷移させます。
サインアウトには、GET /session/が受け付けるアクセストークンが必要です。つまり、有効期限が切れておらず、リフレッシュによって置き換えられていないトークンです。401が返った場合、セッションは終了していません。リフレッシュしてから、新しいアクセストークンでサインアウトしてください。リフレッシュが400で失敗した場合、そのセッションはもう使用できません。
セッションは次の場合にも終了します。
session_lifetime(デフォルトは30日)またはidle_timeout(デフォルトは1日)を経過した場合- 複数セッションが無効な状態で、ユーザーが再度サインインした場合
revoke_on_password_changeが有効な状態で、ユーザーがパスワードをリセットした場合- チームがコンソールでセッションを取り消すか、ユーザーをブロックした場合
- 使用済みのリフレッシュトークンが再送信された場合
有効期間
用途に応じた認証情報の保管
- 認証用のAPIキーとコンソールトークンはサーバー上に保管してください。
- ブラウザーのアクセストークンは、可能な限りメモリ上に保持してください。サーバーサイドでレンダリングされるアプリでは、Secure属性とHttpOnly属性を付けたCookieを使用し、Cookieで認証するリクエストをCSRFから保護してください。
- モバイルのリフレッシュトークンは、プラットフォームが保護するストレージに保存してください。サインアウト後はローカルの状態を消去してください。
- トークンをURLやログに含めてはいけません。