トークンの有効期間、有効期限、更新

ここから始める前に、 ログイン して トークンを取得する方法を理解していることを確認してください。

MSAL.jsを使用するときは、ユーザーのトークンを取得することの影響と、これらのトークンの有効期間を管理する方法を理解する必要があります。

トークンの有効期間と有効期限

Microsoft ID プラットフォームによって発行されたアクセス、ID、またはセキュリティ アサーション マークアップ言語 (SAML) トークンのトークンの有効期間を構成できます。 情報の一部を以下にまとめます。

ID トークン

ID トークンはアカウントとクライアントの特定の組み合わせにバインドされ、通常はユーザーに関するプロファイル情報が含まれます。 通常、Web アプリケーションのユーザー セッションの有効期間は、ID トークン セッションの有効期間 (既定では 24 時間) の有効期間と一致します。 トークンの有効期間の構成について詳しくは、こちらをご覧ください。

アクセス トークン

ブラウザーのアクセス トークンの既定の推奨有効期限は 1 時間です。 この 1 時間後、期限切れのトークンを使用したベアラー呼び出しはすべて拒否されます。 このトークンは、このトークンで取得された更新トークンを使用して、サイレントモードで更新できます。 トークンの有効期間の構成について詳しくは、こちらをご覧ください。

更新トークン

Single-Page アプリケーションに与えられる更新トークンは、限られた時間の更新トークンです (通常、取得時から 24 時間)。 これは、調整不可で、スライドしないウィンドウの有効期間です。 更新トークンを使用してアクセス トークンを更新するたびに、更新されたアクセス トークンを使用して新しい更新トークンがフェッチされます。 この新しい更新トークンの有効期間は、元の更新トークンの残りの有効期間と同じです。 更新トークンの有効期限が切れると、新しい承認コード フローを開始して承認コードを取得し、それを新しいトークン セットと交換する必要があります。

注: 新しい更新トークンが取得されると、msal.js はキャッシュされた更新トークンを新しい更新トークンに置き換えますが、古い更新トークンはサーバーによって無効にされず、有効期限が切れるまでアクセス トークンを取得するために引き続き使用できます。

トークンの更新

PublicClientApplication オブジェクトは、期限切れでないトークンをサイレントモードで取得することを目的として、acquireTokenSilentという API を公開します。 これは、いくつかの手順で行われます。

  1. 特定の scopesclient idauthority、または homeAccountIdentifierのトークン キャッシュにトークンが既に存在するかどうかを確認します。
  2. 指定されたパラメーターにトークンが存在する場合は、1 つの一致を取得し、有効期限を確認します。
  3. アクセス トークンの有効期限が切れていない場合、MSAL は関連するトークンを含む応答を返します。
  4. アクセス トークンの有効期限が切れているが、更新トークンがまだ有効な場合、MSAL は指定された更新トークンを使用して新しいトークンのセットを取得し、応答を返します。
  5. 更新トークンの有効期限が切れている場合、MSAL は非表示の iframe を使用してアクセス トークンをサイレント モードで取得しようとします。 これにより、アカウントの要求オブジェクトの sid またはユーザー名が使用され、ユーザーのセッションに関するヒントが取得されます。 この非表示の iframe 呼び出しが失敗した場合、MSAL はサーバーからエラーを InteractionRequiredAuthErrorとして渡し、新しいトークン セットを取得するための承認コードを取得するように求めます。 これを行うには、 PublicClientApplication オブジェクトで login または acquireToken API 呼び出しを実行します。 セッションがまだアクティブな場合、サーバーはユーザー プロンプトなしでコードを送信します。 それ以外の場合、ユーザーは資格情報を入力する必要があります。

メソッドに設定できる構成パラメーターの詳細については、acquireTokenSilentに関する記事を参照してください。

ユーザーのセッションの途中で対話型の中断を回避する

場合によっては、必要に応じて、ユーザーのセッションの開始時に対話を事前に呼び出して、ユーザーがトークンをサイレントモードで取得し、さらに中断することなくアプリケーションを使用できるようにすることができます。 もちろん、これは、アプリケーションが初めて読み込まれるたびに対話を呼び出すことによって実現できます。ただし、ユーザーエクスペリエンスが低下し、ユーザーが以前のセッションまたは別のウィンドウ/タブからトークンを既に持っている場合はパフォーマンスが低下します。代わりに、いくつかの要求パラメーターを使用して、 acquireTokenSilent を使用して、任意の長さの間、キャッシュがサイレントモードで返すために必要なトークンを持っていることを確認できます。

acquireTokenSilentが有効なトークンを最低 1 時間返すことができるようにするには、次のようにします。

  • acquireTokenSilent要求パラメーターを forceRefresh に設定して、ページ読み込み時にtrueを呼び出します。 これにより、キャッシュがスキップされ、以降の呼び出しでキャッシュから提供できる新しいトークンが取得されます。
  • 後続の呼び出しでは forceRefresh 設定を解除するか、明示的に false して、トークンをキャッシュから提供できるようにします

acquireTokenSilentが、最大 24 時間の任意の長さの有効なトークンを返すことができるようにするには、次のようにします。

  • acquireTokenSilent要求パラメーターを forceRefresh に設定し、true パラメーターを対話なしの目的の時間 (秒単位) に設定して、ページ読み込み時にrefreshTokenExpirationOffsetSecondsを呼び出します
  • 後続の呼び出しでは、 forceRefresh を残し、 refreshTokenExpirationOffsetSeconds 設定を解除して、キャッシュからトークンを確実に処理できるようにします。

たとえば、次の 2 時間、ユーザーがトークンをサイレントモードで取得できるようにする場合は、次のようにします。

var request = {
    scopes: ["Mail.Read"],
    account: currentAccount,
    forceRefresh: true,
    refreshTokenExpirationOffsetSeconds: 7200 // 2 hours * 60 minutes * 60 seconds = 7200 seconds
};

const tokenResponse = await msalInstance.acquireTokenSilent(request).catch(async (error) => {
    if (error instanceof InteractionRequiredAuthError) {
        // fallback to interaction when silent call fails
        await msalInstance.acquireTokenRedirect(request);
    }
});

注: 更新トークンの有効期限がまだ切れていない場合でも、トークンをサイレントで取得できる保証はありません。 上記のパターンは、不便な時に相互作用を最小限に抑えるためのベスト エフォートの試みですが、必要な時間内に必要な相互作用の可能性を排除することはできません。 さらに、すべての ID プロバイダーが更新トークンの有効期限を返すわけではありません。このような場合、 refreshTokenExpirationOffsetSeconds 要求パラメーターは評価されません。

キャッシュ参照ポリシー

キャッシュ参照ポリシーは、必要に応じて要求に提供できます。 キャッシュ参照ポリシーは次のとおりです。

  • CacheLookupPolicy.Default - acquireTokenSilent は、キャッシュからアクセス トークンの取得を試みます。 アクセス トークンの有効期限が切れているか、見つからない場合は、更新トークンを使用して新しいトークンを取得します。 最後に、更新トークンの有効期限が切れている場合、 acquireTokenSilent は、新しいアクセス トークン、ID トークン、および更新トークンを自動的に取得しようとします。
  • CacheLookupPolicy.AccessToken - acquireTokenSilent では、キャッシュ内のアクセス トークンのみが検索されます。 アクセス トークンまたは更新トークンの更新を試行しません。
  • CacheLookupPolicy.AccessTokenAndRefreshToken - acquireTokenSilent は、キャッシュからアクセス トークンの取得を試みます。 アクセス トークンの有効期限が切れているか、見つからない場合は、更新トークンを使用して新しいトークンが取得されます。 更新トークンの有効期限が切れている場合、更新されず、 acquireTokenSilent は失敗します。
  • CacheLookupPolicy.RefreshToken - acquireTokenSilent はキャッシュからアクセス トークンを取得しようとせず、キャッシュされた更新トークンを新しいアクセス トークンと交換しようとします。 更新トークンの有効期限が切れている場合、更新されず、 acquireTokenSilent は失敗します。
  • CacheLookupPolicy.RefreshTokenAndNetwork - acquireTokenSilent は、アクセス トークンのキャッシュを検索しません。 キャッシュされた更新トークンを使用してネットワークに直接移動します。 更新トークンの有効期限が切れている場合は、更新が試行されます。 これは、 forceRefresh: trueの設定と同じです。
  • CacheLookupPolicy.Skip - acquireTokenSilent は、アクセス トークンと更新トークンの両方の更新を試みます。 キャッシュ内では検索されません。 サード パーティの Cookie がブラウザーによってブロックされている場合、これは常に失敗します。

コード スニペット

var username = "test@contoso.com";
var currentAccount = msalInstance.getAccount({ username });
var silentRequest = {
    scopes: ["Mail.Read"],
    account: currentAccount,
    forceRefresh: false,
    cacheLookupPolicy: CacheLookupPolicy.Default // will default to CacheLookupPolicy.Default if omitted
};

var request = {
    scopes: ["Mail.Read"],
    loginHint: currentAccount.username // For v1 endpoints, use upn from idToken claims
};

const tokenResponse = await msalInstance.acquireTokenSilent(silentRequest).catch(async (error) => {
    if (error instanceof InteractionRequiredAuthError) {
        // fallback to interaction when silent call fails
        return await msalInstance.acquireTokenPopup(request).catch(error => {
            if (error instanceof InteractionRequiredAuthError) {
                // fallback to interaction when silent call fails
                return msalInstance.acquireTokenRedirect(request)
            }
        });
    }
});

リダイレクト

var username = "test@contoso.com";
var currentAccount = msalInstance.getAccount({ username });
var silentRequest = {
    scopes: ["Mail.Read"],
    account: currentAccount,
    forceRefresh: false,
    cacheLookupPolicy: CacheLookupPolicy.Default // will default to CacheLookupPolicy.Default if omitted
};

var request = {
    scopes: ["Mail.Read"],
    loginHint: currentAccount.username // For v1 endpoints, use upn from idToken claims
};

const tokenResponse = await msalInstance.acquireTokenSilent(silentRequest).catch(error => {
    if (error instanceof InteractionRequiredAuthError) {
        // fallback to interaction when silent call fails
        return msalInstance.acquireTokenRedirect(request)
    }
});

次のステップ

ログアウトを実行する方法について説明します。