> ## Documentation Index
> Fetch the complete documentation index at: https://docs-dev-docs-event-stream-action-templates.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# サイレント認証を設定する

> サイレント認証を使用してユーザーがアプリケーションにログインしたままにする方法を説明します。

export const AuthCodeBlock = ({filename, icon, language, highlight, children}) => {
  const [displayText, setDisplayText] = useState(children);
  const [copyText, setCopyText] = useState(children);
  const wrapperRef = React.useRef(null);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      if (!window.autorun || !window.rootStore) {
        return;
      }
      unsubscribe = window.autorun(() => {
        let processedChildrenForDisplay = children;
        let processedChildrenForCopy = children;
        for (const [key, value] of window.rootStore.variableStore.values.entries()) {
          const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
          let displayValue = value;
          if (key === "{yourClientSecret}" && value !== "{yourClientSecret}") {
            displayValue = value.substring(0, 3) + "*****MASKED*****";
          }
          processedChildrenForDisplay = processedChildrenForDisplay.replaceAll(new RegExp(escapedKey, "g"), displayValue);
          processedChildrenForCopy = processedChildrenForCopy.replaceAll(new RegExp(escapedKey, "g"), value);
        }
        setDisplayText(processedChildrenForDisplay);
        setCopyText(processedChildrenForCopy);
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  useEffect(() => {
    if (!wrapperRef.current) return;
    const originalWriteText = navigator.clipboard.writeText.bind(navigator.clipboard);
    let isOverriding = false;
    const handleClick = e => {
      const button = e.target.closest('[data-testid="copy-code-button"]');
      if (!button || !wrapperRef.current.contains(button)) return;
      isOverriding = true;
      navigator.clipboard.writeText = text => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
          return originalWriteText(copyText);
        }
        return originalWriteText(text);
      };
      setTimeout(() => {
        if (isOverriding) {
          isOverriding = false;
          navigator.clipboard.writeText = originalWriteText;
        }
      }, 100);
    };
    const wrapper = wrapperRef.current;
    wrapper.addEventListener('click', handleClick, true);
    return () => {
      wrapper.removeEventListener('click', handleClick, true);
      if (navigator.clipboard.writeText !== originalWriteText) {
        navigator.clipboard.writeText = originalWriteText;
      }
    };
  }, [copyText]);
  return <div ref={wrapperRef}>
      <CodeBlock filename={filename} icon={icon} language={language} lines highlight={highlight}>
        {displayText}
      </CodeBlock>
    </div>;
};

[OpenID Connectのプロトコル](/docs/ja-jp/authenticate/protocols/openid-connect-protocol)は、認証要求の`prompt=none`パラメーターをサポートしているので、アプリケーションは、認証サーバーにユーザーとのやりとり（認証や承諾、<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" href="/docs/ja-jp/glossary?term=multifactor-authentication" tip="多要素認証（MFA）: ユーザー名とパスワードに加えて、SMS経由のコードなどの要素を使用するユーザー認証プロセス。" cta="用語集の表示">MFA</Tooltip>など）を一切表示しないよう指示できます。Auth0は要求された応答をアプリケーションに返すか、ユーザーがまだ認証されていない場合や、処理を進める前に何らかの同意やプロンプトが必要な場合はエラーを返します。

SPAで[暗黙フロー](/docs/ja-jp/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post)を使用すると、明示的な緩和策を必要とするセキュリティ上の課題につながります。[PKCEを使った認可コードフロー](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce)をサイレント認証と組み合わせて使用することで、SPAのセッションを更新できます。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  近年、ブラウザーのユーザープライバシー制御機能が発達し、サードパーティクッキーがブロックされることでユーザーエクスペリエンスに悪影響を与えています。そのため、ブラウザーベースのフローは、[リフレッシュトークンのローテーション](/docs/ja-jp/secure/tokens/refresh-tokens/refresh-token-rotation)を使用しなければなりません。これにより、SPAで安全にリフレッシュトークンが使用できる一方で、ブラウザーにあるITPなどのプライバシー保護技術にUXを阻害されることなく、エンドユーザーがリソースにシームレスにアクセスできます。
</Callout>

## サイレント認証要求を開始する

サイレント認証要求を開始するには、[Auth0の認証APIのエンドポイント`/authorize`](/docs/ja-jp/api/authentication#authorize-application)にユーザーをリダイレクトする際に、`prompt=none`パラメーターを追加します。（認証要求の個々のパラメーターは、アプリの特定のニーズに応じて異なります）。

例：

export const codeExample = `GET https://{yourDomain}/authorize
    ?response_type=id_token token&
    client_id=...&
    redirect_uri=...&
    state=...&
    scope=openid...&
    nonce=...&
    audience=...&
    response_mode=...&
    prompt=none`;

<AuthCodeBlock children={codeExample} language="json" />

`prompt=none`パラメーターにより、Auth0は指定された`redirect_uri`（コールバックURL）に、指定された`response_mode`を使用して、成功またはエラーの2つのうちいずれかの応答を即座に送信します。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  適用可能な[ルール](/docs/ja-jp/customize/rules)はすべて、サイレント認証処理の一部として実行されます。
</Callout>

### 認証成功の応答

ユーザーがすでにAuth0にログインしており、他の対話型プロンプトが不要な場合、Auth0は、ユーザーがログインページから手動で認証を受けた場合とまったく同じように応答します。

たとえば、暗黙フロー（シングルページアプリケーションで使用される`response_type=id_token token`）を使用すると、Auth0は次のように、要求されたトークンを返します。

```bash cURL lines theme={null}
GET {https://yourApp/callback}
    #id_token=...&
    access_token=...&
    state=...&
    expires_in=...
```

この応答は、`prompt=none`パラメーターを使用せずに直接ログインした場合と区別がつきません。

### エラーの応答

ユーザーがシングルサインオン（<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" href="/docs/ja-jp/glossary?term=single-sign-on" tip="シングルサインオン（SSO）: ユーザーが1つのアプリケーションにログインした後、そのユーザーを他のアプリケーションに自動的にログインさせるサービス。" cta="用語集の表示">SSO</Tooltip>）経由でログインしていなかった場合、またはSSOセッションが期限切れとなっていた場合、Auth0は次のように、指定された`redirect_uri`（コールバックURL）にエラーとともにリダイレクトします。

```json lines theme={null}
GET https://your_callback_url/
    #error=ERROR_CODE&
    error_description=ERROR_DESCRIPTION&
    state=...
```

`ERROR_CODE`が取り得る値は、[OpenID Connect仕様](https://openid.net/specs/openid-connect-core-1_0.html#AuthError)によって次のように定義されています。

| 応答                     | 説明                                                                                                                                                                                                                                                                                       |
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `login_required`       | ユーザーがAuth0でログインしていないため、サイレント認証は不可能です。このエラーは、テナントレベルの **Log In Session Management（ログインセッション管理）** 設定の構成方法に基づいて起こります。特に、 **Require log in after（後にログインが必要）** 設定で指定された期間後に起こります。詳細については、[セッションライフタイム設定の構成](/docs/ja-jp/dashboard/guides/tenants/configure-session-lifetime-settings)をご覧ください。 |
| `consent_required`     | ユーザーはAuth0でログインしましたが、アプリケーションの認可に同意が必要です。                                                                                                                                                                                                                                                |
| `interaction_required` | ユーザーはAuth0でログインし、アプリケーションを認可しましたが、認証が完了する前にどこか他にリダイレクトされる必要があります。たとえば、[リダイレクトルール](/docs/ja-jp/rules/redirect)を使用している場合などです。                                                                                                                                                              |

これらのいずれかのエラーが返された場合、ユーザーは`prompt=none`パラメーターなしでAuth0のログインページにリダイレクトされて、認証を受ける必要があります。

## 期限切れトークンを更新する

ユーザーがAuth0で有効なセッションを保持している限り、新しいトークンを取得するためにサイレント認証要求を行うことができます。[auth0.jsのメソッド`checkSession`](/docs/ja-jp/libraries/auth0js)は、SPA用に`response_mode=web_message`と組み合わせてサイレントトークン要求を使用して、要求が非表示のiframe内で実行されるようにします。SPAでは、Auth0.jsが結果処理（トークンまたはエラーコード）を処理し、アプリケーションが提供するコールバック関数を通じて情報を渡します。これにより、UXが中断されること（ページの再読み込みや状態の喪失）はありません。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  Safariブラウザーに関する他の重要な制限事項や回避方法については、「[Safariを使ってトークンを更新する](/docs/ja-jp/troubleshoot/authentication-issues/renew-tokens-when-using-safari)」を参照してください。
</Callout>

### アクセストークンの有効期限

アクセストークンはアプリケーションに対して不透明です。つまり、アプリケーションはアクセストークンの有効期限を判断するためにその内容を検査できません。

アクセストークンの有効期限を判断するには、2通りの方法があります。

* Auth0から返される`expires_in`応答パラメーターを読み取りる。
* 有効期限は完全に無視する。その代わりに、アプリケーションからの要求をAPIが拒否した場合（401など）にアクセストークンを更新する。

[暗黙フロー](/docs/ja-jp/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post)の場合、認証が成功すると、Auth0から`expires_in`パラメーターがハッシュパラメーターとして返されます。[PKCEを使った認可コードフロー](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce)では、認可コードの交換を行う際にバックエンドサーバーにこのパラメーターが返されます。

`expires_in`パラメーターは、アクセストークンが何秒間有効であるかを示し、アクセストークンの有効期限切れを予測するために使用できます。

### エラーの応答

`web_message`通信の実行中にタイムアウトが発生したことを示す`timeout`エラー応答を受信することがあります。このエラーは通常、クロスオリジン認証へのフォールバックと関連しています。解決するには、<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" href="/docs/ja-jp/glossary?term=auth0-dashboard" tip="Auth0 Dashboard: サービスを構成するためのAuth0の主製品。" cta="用語集の表示">Auth0 Dashboard</Tooltip>を使用して、サイレント認証を実行したいすべてのURLを、アプリケーションの **［Allowed Web Origins（許可されているWebオリジン）］** フィールドに追加してください。

## checkSession()でポーリングする

シングルログアウトが必要な一部のマルチアプリケーションのシナリオ（あるアプリケーションからログアウトするユーザーが他のアプリケーションからもログアウトする必要があるような場合）では、`checkSession()`を使用して定期的にAuth0をポーリングし、セッションが存在するかどうかを確認するようにアプリケーションを設定できます。セッションがない場合は、ユーザーをアプリケーションからログアウトさせることができます。同じポーリング方式を使用して、シングルサインオン（SSO）のシナリオにサイレント認証を実装することができます。

ポーリング間隔として、`checkSession()`の呼び出し間隔を15分以上に設定し、レート制限の問題が生じないようにします。

## 多要素認証によるサイレント認証

状況によっては、同じブラウザーを使ってログインしているユーザーに対し、[多要素認証（MFA）](/docs/ja-jp/secure/multi-factor-authentication)を求めるプロンプトを毎回表示したくない場合があります。これを実行するには、セッションごとにMFAが1回だけ発生するようにアクションを設定します。これは、`allowRememberBrowser`を`true`に設定することなく、ユーザーのセッションの期間中に、SPA内で有効期限の短いアクセストークンを更新するためのサイレント認証（`prompt=none`）を行う場合に便利です。

```js lines theme={null}
exports.onExecutePostLogin = async (event, api) => {
  const authMethods = event.authentication?.methods || []

  const completedMfa = !!authMethods.find((method) => method.name === 'mfa')

  if (!completedMfa) {
    api.multifactor.enable('any', { allowRememberBrowser: true })
  }
};
```

詳細については、[認証要求頻度を変更する](/docs/ja-jp/secure/multi-factor-authentication/customize-mfa)を参照してください。

## もっと詳しく

* [リフレッシュトークンのローテーション](/docs/ja-jp/secure/tokens/refresh-tokens/refresh-token-rotation)
* [リフレッシュトークンのローテーションを構成する](/docs/ja-jp/secure/tokens/refresh-tokens/configure-refresh-token-rotation)
* [無効なトークンエラーのトラブルシューティング](/docs/ja-jp/troubleshoot/basic-issues/invalid-token-errors)
* [APIの呼び出しをチェックする](/docs/ja-jp/troubleshoot/authentication-issues/check-api-calls)
* [多要素認証問題をトラブルシューティングする](/docs/ja-jp/troubleshoot/authentication-issues/troubleshoot-mfa-issues)
