> ## Documentation Index
> Fetch the complete documentation index at: https://translations.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

> PKCE を使用した認可コードグラントフロー向けのシングルページアプリケーション用 Auth0 SDK。

# PKCE を使用した Auth0 Single Page App SDK の認可コードグラントフロー。

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) + "*****マスク済み*****";
          }
          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>;
};

Auth0 Single Page App SDK は、Auth0 を使用してシングルページアプリ (SPA) に認証と認可を実装するための新しい JavaScript ライブラリです。高水準の API を提供し、多くの複雑な処理を担うため、ベストプラクティスに従って SPA を保護しつつ、記述するコード量を減らせます。

Auth0 SPA SDK は、グラントやプロトコルの詳細、トークンの有効期限と更新に加え、トークンの保存とキャッシュも処理します。内部では、[Universal Login](/ja/docs/authenticate/login/auth0-universal-login) と [PKCE を使用した認可コードグラントフロー](/ja/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) を実装しています。

[ライブラリ](https://github.com/auth0/auth0-spa-js) と [API ドキュメント](https://auth0.github.io/auth0-spa-js/) は GitHub で公開されています。

新しい JavaScript SDK の使用中に問題やエラーが発生した場合は、[FAQ を参照して](https://github.com/auth0/auth0-spa-js/blob/master/FAQ.md)、該当する事象が掲載されているか確認してください。

<div id="installation">
  ## インストール
</div>

プロジェクトで Auth0 SPA SDK を使用するには、いくつかの方法があります。

* CDN から使用する: `<script src="https://cdn.auth0.com/js/auth0-spa-js/2.0/auth0-spa-js.production.js"></script>`。詳細は、[FAQ](https://github.com/auth0/auth0-spa-js/blob/main/FAQ.md#how-to-use-from-a-cdn)を参照してください。
* [npm](https://npmjs.org) を使用する: `npm install @auth0/auth0-spa-js`
* [yarn](https://yarnpkg.com) を使用する: `yarn add @auth0/auth0-spa-js`

<div id="getting-started">
  ## はじめに
</div>

<div id="create-the-client">
  ### クライアントを作成する
</div>

まず、`Auth0Client` クライアントオブジェクトの新しいインスタンスを作成する必要があります。アプリケーションをレンダリングまたは初期化する前に、`Auth0Client` インスタンスを作成してください。これは、async/await または Promise を使用して行えます。作成するクライアントインスタンスは 1 つだけにしてください。

`createAuth0Client` を使用すると、いくつかの処理が自動的に行われます。

* `Auth0Client` のインスタンスを作成します。
* `getTokenSilently` を呼び出して、ユーザーセッションを更新します。
* `getTokenSilently` から返されるすべてのエラーを抑制します (`login_required` を除く) 。

<div id="use-asyncawait">
  #### async/await を使用する
</div>

export const codeExample1 = `import { createAuth0Client } from '@auth0/auth0-spa-js';

const auth0 = await createAuth0Client({
  domain: '{yourDomain}',
  clientId: '{yourClientId}'
});`;

<AuthCodeBlock children={codeExample1} language="jsx" />

#### Promiseを使用する

export const codeExample2 = `createAuth0Client({
  domain: '{yourDomain}',
  clientId: '{yourClientId}'
}).then(auth0 => {
  //...
});`;

<AuthCodeBlock children={codeExample2} language="jsx" />

`Auth0Client` コンストラクターを使って、クライアントを直接作成することもできます。これは、次のような場合に便利です。

* 初期化時の `getTokenSilently` の呼び出しを省略する。
* 独自のエラー処理を行う。
* SDK を同期的に初期化する。

export const codeExample3 = `import { Auth0Client } from '@auth0/auth0-spa-js';

const auth0 = new Auth0Client({
  domain: '{yourDomain}',
  clientId: '{yourClientId}'
});`;

<AuthCodeBlock children={codeExample3} language="jsx" />

<div id="login-and-get-user-info">
  ### ログインしてユーザー情報を取得する
</div>

次に、ユーザーがクリックしてログインを開始できるボタンを作成します。

`<button id="login">Click to Login</button>`

作成したボタンでクリックイベントをリッスンします。イベントが発生したら、使用するログイン方法でユーザーを認証します (この例では `loginWithRedirect()` を使用します) 。ユーザーの認証後、`getUser()` メソッドを使ってユーザープロファイルを取得できます。

<div id="use-asyncawait">
  #### async/await を使用する
</div>

```jsx lines theme={null}
document.getElementById('login').addEventListener('click', async () => {
  await auth0.loginWithRedirect({
    authorizationParams: {
      redirect_uri: 'http://localhost:3000/'
    }
  });
  //ログインしました。次のようにユーザープロファイルを取得できます:
  const user = await auth0.getUser();
  console.log(user);
});
```

#### Promiseを使用する

```jsx lines theme={null}
document.getElementById('login').addEventListener('click', () => {
  auth0.loginWithRedirect({
    authorizationParams: {
      redirect_uri: 'http://localhost:3000/'
    }
  }).then(token => {
    //ログインしました。次のようにユーザープロファイルを取得できます:
    auth0.getUser().then(user => {
      console.log(user);
    });
  });
});
```

<div id="call-an-api">
  ### API を呼び出す
</div>

API を呼び出すには、まずユーザーの <Tooltip tip="アクセストークン: API へのアクセスに使用される、不透明な文字列または JWT の形式の認可資格情報。" cta="用語集を表示" href="/ja/docs/glossary?term=Access+Token">アクセストークン</Tooltip> を取得します。次に、そのアクセストークンをリクエストで使用します。この例では、`getTokenSilently` メソッドを使用してアクセストークンを取得します。

`<button id="callApi">Call an API</button>`

<div id="use-asyncawait">
  #### async/await を使用する
</div>

```jsx lines theme={null}
document.getElementById('callApi').addEventListener('click', async () => {
  const accessToken = await auth0.getTokenSilently();
  const result = await fetch('https://exampleco.com/api', {
    method: 'GET',
    headers: {
      Authorization: 'Bearer ' + accessToken
    }
  });
  const data = await result.json();
  console.log(data);
});
```

<div id="use-promises">
  #### Promise を使用する
</div>

```jsx lines theme={null}
document.getElementById('callApi').addEventListener('click', () => {
  auth0
    .getTokenSilently()
    .then(accessToken =>
      fetch('https://exampleco.com/api', {
        method: 'GET',
        headers: {
          Authorization: 'Bearer ' + accessToken
        }
      })
    )
    .then(result => result.json())
    .then(data => {
      console.log(data);
    });
});
```

<div id="logout">
  ### ログアウト
</div>

ユーザーがクリックしてログアウトできるよう、ボタンを追加します。

`<button id="logout">Logout</button>`

```jsx lines theme={null}
$('#logout').click(async () => {
  auth0.logout({
    logoutParams: {
      returnTo: 'http://localhost:3000/'
    }
  });
});
```

<div id="change-storage-options">
  ### ストレージオプションを変更する
</div>

Auth0 SPA SDK は、デフォルトでトークンをメモリ内に保存します。ただし、この方法ではページを再読み込みした場合やブラウザータブをまたいだ場合に保持されません。代わりに、SDK の初期化時に `cacheLocation` プロパティを `localstorage` に設定すると、トークンをローカルストレージに保存できます。これにより、アクセストークンをより長く保持できるため、Auth0 の<Tooltip tip="セッションクッキー: これが存在する場合、ユーザーは認証済みと見なされます。" cta="用語集を見る" href="/ja/docs/glossary?term=session+cookie">セッションクッキー</Tooltip>へのアクセスを妨げるブラウザーのプライバシー保護機能の影響を一部軽減できます。

<Warning>
  ブラウザーのローカルストレージにトークンを保存すると、ページの再読み込み後やブラウザータブをまたいでも保持されます。ただし、攻撃者がクロスサイトスクリプティング (XSS) 攻撃によって SPA 上で JavaScript を実行できた場合、ローカルストレージに保存されたトークンを取得される可能性があります。XSS 攻撃の成功につながる脆弱性は、SPA のソースコードにある場合もあれば、SPA に含まれるサードパーティ製 JavaScript コード (bootstrap、jQuery、Google Analytics など) にある場合もあります。

  詳細は、[トークンの保存](/ja/docs/secure/tokens/token-best-practices)を参照してください。
</Warning>

export const codeExample4 = `const auth0 = await createAuth0Client({
  domain: '{yourDomain}',
  clientId: '{yourClientId}',
  cacheLocation: 'localstorage'
});`;

<AuthCodeBlock children={codeExample4} language="jsx" />

<div id="use-rotating-refresh-tokens">
  ### ローテーション型のリフレッシュトークンを使用する
</div>

Auth0 SPA SDK は、[ローテーション型のリフレッシュトークン](/ja/docs/secure/tokens/refresh-tokens/refresh-token-rotation)を使用して、新しいアクセストークンをサイレントに取得するよう設定できます。これにより、サイレント認証時に Auth0 のセッションクッキーへのアクセスを妨げるブラウザーのプライバシー保護機能を回避できるほか、組み込みの再利用検出も利用できます。

これを有効にするには、初期化時に `useRefreshTokens` を `true` に設定します。

export const codeExample5 = `const auth0 = await createAuth0Client({
  domain: '{yourDomain}',
  clientId: '{yourClientId}',
  useRefreshTokens: true
});

// リフレッシュトークンを使用して新しいアクセストークンを取得します
const token = await auth0.getTokenSilently();`;

<AuthCodeBlock children={codeExample5} language="jsx" />

<Tooltip tip="リフレッシュトークン: ユーザーに再度ログインさせることなく、新しいアクセストークンを取得するために使用するトークンです。" cta="用語集を見る" href="/ja/docs/glossary?term=Refresh+Tokens">リフレッシュトークン</Tooltip> を SPA で使用するには、あらかじめ[テナントで設定](/ja/docs/secure/tokens/refresh-tokens/configure-refresh-token-rotation)しておく必要があります。

設定すると、SDK は認可ステップで `offline_access` スコープをリクエストします。さらに、`getTokenSilently` は `/oauth/token` エンドポイントを直接呼び出し、リフレッシュトークンをアクセストークンに交換します。
SDK は、リフレッシュトークンの保存時にストレージ設定に従います。SDK がデフォルトのインメモリストレージを使用するように設定されている場合、ページを更新するとリフレッシュトークンは失われます。

<div id="usage">
  ## 使用例
</div>

以下に、SDK の各種メソッドの使用例を示します。これらの例では jQuery を使用しています。

<div id="login-with-redirect">
  ### リダイレクトによるログイン
</div>

Auth0 の `/authorize` エンドポイントにリダイレクトし、[Universal Login](/ja/docs/authenticate/login/auth0-universal-login) フローを開始します。

```jsx lines theme={null}
$('#loginRedirect').click(async () => {
  await auth0.loginWithRedirect({
    authorizationParams: {
      redirect_uri: 'http://localhost:3000/'
    }
  });
});
```

<div id="login-with-popup">
  ### ポップアップでログイン
</div>

ポップアップウィンドウを使用して、<Tooltip tip="Universal Login: アプリケーションはユーザーの本人確認のため、Auth0 の認可サーバーでホストされる Universal Login にリダイレクトされます。" cta="用語集を表示" href="/ja/docs/glossary?term=Universal+Login">Universal Login</Tooltip> ページでログインします。

```jsx lines theme={null}
$('#loginPopup').click(async () => {
  await auth0.loginWithPopup();
});
```

ユーザーが認証フローの完了にデフォルトのタイムアウトである 60 秒以上かかると、認証は中断されます。その場合は、コード内でエラーをキャッチして、次のいずれかの対応を行う必要があります。

ユーザーに再試行を促し、`error.popup.close` を使用してポップアップを手動で閉じるよう案内します。

```jsx lines theme={null}
$('#loginPopup').click(async () => {
  try {
    await auth0.loginWithPopup();
  } catch {error}
  if (error instanceof auth0.PopupTimeoutError) {
    // ユーザーに再試行を促すカスタムロジック
    error.popup.close();
  }
});
```

または、`options` オブジェクトでカスタムの `popup` オプションを定義します。

```jsx lines theme={null}
$('#loginPopup').click(async () => {
  const popup = window.open(
    '',
    'auth0:authorize:popup',
    'left=100,top=100,width=400,height=600,resizable'
  );
  try {
    await auth0.loginWithPopup({ popup });
  } catch {error}
  if (error instanceof auth0.PopupTimeoutError) {
    // ユーザーに再試行を促すカスタムロジック
    error.popup.close();
  }
});
```

<div id="login-with-redirect-callback">
  ### リダイレクトコールバックでログインする
</div>

ブラウザーが Auth0 から SPA にリダイレクトで戻ったら、ログインフローを完了するために `handleRedirectCallback` を呼び出す必要があります。

```jsx lines theme={null}
$('#loginRedirectCallback').click(async () => {
  await auth0.handleRedirectCallback();
});
```

<div id="get-access-token-with-no-interaction">
  ### ユーザー操作なしでアクセストークンを取得する
</div>

非表示の iframe と `prompt=none` を使用する方法、またはローテーションされるリフレッシュトークンを使用する方法で、新しいアクセストークンをサイレントに取得できます。リフレッシュトークンは、SDK の設定時に `useRefreshTokens` を `true` に設定した場合に使用されます。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  リフレッシュトークンを使用せずにアクセストークンをサイレントに取得する方法は、Safari や Brave など、サードパーティ Cookie をブロックするブラウザーでは機能しません。カスタムドメインを使用した回避策の詳細については、[Safari 使用時のトークンの更新に関するトラブルシューティング](https://support.auth0.com/center/s/article/troubleshoot-auth0-token-renewal-issues-in-safari-with-itp-enabled) を参照してください。
</Callout>

インメモリストレージ (デフォルト) とリフレッシュトークンを使用している場合、対応ブラウザーでは Web Worker を使って新しいトークンを取得します。

```jsx lines theme={null}
$('#getToken').click(async () => {
  const token = await auth0.getTokenSilently();
});
```

`getTokenSilently()` メソッドを使用するには、[Dashboard の API Settings](https://manage.auth0.com/#/apis) で **Allow Skipping User Consent** を有効にする必要があります。なお、['localhost' ではユーザーの同意をスキップできません](/ja/docs/get-started/applications/third-party-applications/user-consent-and-third-party-applications)。

<div id="get-access-token-with-popup">
  ### ポップアップでアクセストークンを取得する
</div>

アクセストークンは、ポップアップウィンドウを使って取得することもできます。`getTokenSilently` とは異なり、この方法では、サードパーティ Cookie がデフォルトでブロックされているブラウザーでもアクセストークンを取得できます。

```jsx lines theme={null}
$('#getTokenPopup').click(async () => {
  const token = await auth0.getTokenWithPopup({
    authorizationParams: {
      audience: 'https://mydomain/api/',
      scope: 'read:rules'
    }
  });
});
```

<div id="get-access-token-for-a-different-audience">
  ### 別のオーディエンス向けのアクセストークンを取得する
</div>

`getTokenSilently` にオプションを渡すことで、ユーザー認証時に要求したものとは異なる <Tooltip tip="オーディエンス: 発行されたトークンの対象となるオーディエンスの一意の識別子です。トークン内では aud という名前で表され、その値には IDトークンの場合はアプリケーション（クライアントID）の ID、アクセストークンの場合は API（API Identifier）の ID が含まれます。" cta="用語集を表示" href="/ja/docs/glossary?term=audience">オーディエンス</Tooltip> とスコープを持つアクセストークンを取得できます。

<Callout icon="file-lines" color="#0EA5E9" iconType="regular">
  これはリフレッシュトークンを使用していない場合 (`useRefreshTokens: false`) にのみ機能します。リフレッシュトークンは、ユーザー認証時に要求された特定のオーディエンスとスコープに紐付けられているためです。
</Callout>

```jsx lines theme={null}
$('#getToken_audience').click(async () => {
  const differentAudienceOptions = {
    authorizationParams: {
      audience: 'https://mydomain/another-api/',
      scope: 'read:rules',
      redirect_uri: 'http://localhost:3000/callback.html'
    }
  };
  const token = await auth0.getTokenSilently(differentAudienceOptions);
});
```

<div id="get-user">
  ### ユーザーの取得
</div>

`getUser` メソッドを呼び出すと、認証済みユーザーのプロファイルデータを取得できます。

```jsx lines theme={null}
$('#getUser').click(async () => {
  const user = await auth0.getUser();
});
```

<div id="get-id-token-claims">
  ### IDトークンのクレームを取得する
</div>

認証済みユーザーの<Tooltip tip="IDトークン: リソースへのアクセスではなく、クライアント自体を対象としたクレデンシャルです。" cta="用語集を表示" href="/ja/docs/glossary?term=ID+Token">IDトークン</Tooltip>のクレームは、`getIdTokenClaims` メソッドを呼び出すことで取得できます。

```jsx lines theme={null}
$('#getIdTokenClaims').click(async () => {
  const claims = await auth0.getIdTokenClaims();
  // 生のid_tokenが必要な場合は、__rawプロパティを使って
  // 取得できます
  const id_token = claims.__raw;
});
```

<div id="logout-default">
  ### ログアウト (デフォルト)
</div>

`logout` メソッドを呼び出して、ログアウトを開始できます。

```jsx lines theme={null}
$('#logout').click(async () => {
  auth0.logout({
    logoutParams: {
      returnTo: 'http://localhost:3000/'
    }
  });
});
```

<div id="logout-with-no-client-id">
  ### クライアントIDを指定しないログアウト
</div>

`logout` メソッドを呼び出し、`clientId: null` を指定すると、<Tooltip tip="クライアントID: Auth0 から登録済みリソースに付与される識別値です。" cta="用語集を見る" href="/ja/docs/glossary?term=Client+ID">クライアントID</Tooltip> を指定せずにログアウトを開始できます。

```jsx lines theme={null}
$('#logoutNoClientId').click(async () => {
  auth0.logout({
    clientId: null,
    logoutParams: {
      returnTo: 'http://localhost:3000/'
    }
  });
});
```

<div id="learn-more">
  ## 詳細
</div>

* [アクセストークンを検証する](/ja/docs/secure/tokens/access-tokens/validate-access-tokens)
