> ## 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.

> Auth0 で単一の論理 API を使って複数の API へのアクセスを表現し、管理する方法を学びます。

# 複数の API 向けの論理 API を設定する

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>;
};

export const codeExample = `https://{yourDomain}/authorize?
   scope=read:contacts%20read:calendar&
   audience=organize&
   response_type=id_token%20token&
   client_id={yourClientId}&
   redirect_uri=http://localhost:3000&
   nonce={nonce}
`;

同じ API の一部として論理的にまとまる複数の異なる API 実装がある場合は、それらを <Tooltip tip="Auth0 Dashboard: サービスを設定するための Auth0 の主要プロダクト。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip> で 1 つの論理 API として表すことで、認可プロセスを簡素化できます。こうすることで、実装する <Tooltip tip="Auth0 Dashboard: サービスを設定するための Auth0 の主要プロダクト。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=authorization+flow">認可フロー</Tooltip> は 1 つだけで済みますが、適切なスコープを割り当てることで、個々の API へのアクセスは引き続き制御できます。

以下のセクションでは、複数の API を Auth0 で 1 つの <Tooltip tip="Resource Server: 保護されたリソースをホストするサーバー。リソースサーバーは保護されたリソースへのリクエストを受け取り、応答します。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=Resource+Server">リソースサーバー</Tooltip> として使用し、表現する方法を説明します。例では、次のサンプルアプリケーションを使用します。このサンプルアプリケーションはマイクロサービスアーキテクチャを採用しており、以下を含みます。

* 2 つの Node.js API: `contacts` と `calendar` (マイクロサービスと考えることができます)
* 2 つの API を表す 1 つのリソースサーバー
* 2 つの名前空間付きスコープ: `read:contacts` と `read:calendar`
* 両方の API で機能する `access_token` を取得するためのインプリシットグラントフロー

この 2 つの API は、`Organizer Service` という 1 つの Auth0 API だけを使って表します。次に 2 つのスコープを作成し、[インプリシットフロー](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) を使って SPA から `calendar` API と `contacts` API にアクセスする方法を示します。

次の手順を完了する必要があります。

1. アプリケーションの接続を有効にする
2. テストユーザーを作成する
3. Auth0 に論理 API を登録する
4. 論理 API のスコープを設定する
5. 論理 API へのアクセスを付与する
6. (任意) シングルログアウト (SLO) またはシングルサインオン (SSO) を実装する

<div id="prerequisites">
  ## 前提条件
</div>

* [アプリケーションを登録します](/docs/ja-jp/get-started/auth0-overview/create-applications/single-page-web-apps)。

  * **アプリケーションの種類** で **Single-Page App** を選択します。
  * **Allowed Callback URLs** に `http://localhost:3000` と `http://localhost:3000/callback.html` を追加します。
* [サンプルアプリケーション](https://github.com/auth0-samples/auth0-api-auth-implicit-sample)をダウンロードします。セットアップ方法については、[README](https://github.com/auth0-samples/auth0-api-auth-implicit-sample#readme)を参照してください。

<div id="enable-a-connection-for-your-application">
  ## アプリケーションで接続を有効にする
</div>

新しく登録したアプリケーションでユーザーを利用できるようにするには、ユーザーの情報源として[接続](/docs/ja-jp/authenticate/identity-providers)を設定する必要があります。このサンプルでは、ユーザーのメールアドレスとパスワードだけを求めるシンプルな[データベース接続](/docs/ja-jp/authenticate/database-connections)を作成します。詳しくは、[データベース接続を設定する](/docs/ja-jp/get-started/applications/set-up-database-connections)をご覧ください。

<div id="create-a-test-user">
  ## テストユーザーを作成する
</div>

新しく作成した接続を使用しているため、まだ関連付けられたユーザーはいません。サンプルアプリケーションのログインプロセスをテストする前に、ユーザーを作成してその接続に関連付ける必要があります。ユーザーを作成する際は、必ず新しく作成した接続を選択してください。詳しくは、[ユーザーを作成する](/docs/ja-jp/manage-users/user-accounts/create-users)をご覧ください。

<div id="register-a-logical-api-in-auth0">
  ## Auth0 で論理 API を登録する
</div>

サンプルアプリケーションに含まれる複数の API を表すために使用する、1 つの論理 API を登録します。このサンプルでは、API の名前を `Organizer Service`、一意の識別子を `organize` に設定します。既定では、この API 用に取得するトークンの <Tooltip tip="署名アルゴリズム: トークンが改ざんされていないことを保証するために、トークンに電子署名する際に使用されるアルゴリズム。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=signing+algorithm">署名アルゴリズム</Tooltip> は **RS256** なので、そのままにしておきます。詳しくは、[API を登録する](/docs/ja-jp/get-started/auth0-overview/set-up-apis) を参照してください。

<div id="configure-permissions-for-the-logical-api">
  ## 論理 API の権限を設定する
</div>

サンプルアプリケーションに含まれる API を論理 API が表現できるようにするには、適切な権限 (スコープ) を作成する必要があります。

スコープを使うと、呼び出し元のアプリケーションが利用できる API の操作を定義できます。各スコープは、1 つの API と 1 つの操作の組み合わせに対応します。このサンプルでは、呼び出し元のアプリケーションが `calendar` という API と、`contacts` という別の API から `read` できるようにしたいため、次の権限を作成する必要があります。

* `read:calendar`
* `read:contacts`

それぞれを 1 つのマイクロサービスと考えることができます。詳しくは、[API の権限を追加する](/docs/ja-jp/get-started/apis/add-api-permissions) と [API スコープ](/docs/ja-jp/get-started/apis/scopes/api-scopes) を参照してください。

<div id="grant-access-to-the-logical-api">
  ## 論理 API へのアクセスを付与する
</div>

これで、論理 API が <Tooltip tip="アクセストークン: API へのアクセスに使用される、opaque な文字列または JWT の形式の認可資格情報。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=Access+Tokens">アクセストークン</Tooltip> を取得できるようにすることで、API へのアクセスを提供する準備が整いました。必要なスコープを含めることで、論理 API が表す API に対するアプリケーションのアクセスを制御できます。以下の手順では、サンプルに合わせて [Implicit Flow](/docs/ja-jp/get-started/authentication-and-authorization-flow/implicit-flow-with-form-post) を使用します。ただし、ニーズに最も適したフローを使用できます。たとえば、次のようなものです。

* **Machine-to-Machine Application** がある場合は、[クライアント認証情報フロー](/docs/ja-jp/get-started/authentication-and-authorization-flow/client-credentials-flow) を実行することで、そのアプリケーションが API 用のアクセストークンをリクエストできるように認可できます。
* **Native App** を構築している場合は、[Authorization Code Flow with Proof Key for Code Exchange (PKCE)](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) を実装できます。

認可フローについて詳しくは、[Authentication and Authorization Flows](/docs/ja-jp/get-started/authentication-and-authorization-flow) をお読みください。

1. ユーザーが SPA 内で Login をクリックすると、アプリはユーザーを Auth0 認可サーバー (`/authorize` エンドポイント) にリダイレクトします。このリクエストのパラメーターについて詳しくは、チュートリアル「[Call Your API Using the Authorization Code Flow with PKCE](/docs/ja-jp/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce/call-your-api-using-the-authorization-code-flow-with-pkce)」をご覧ください。

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

   <Frame>
     <img src="https://mintcdn.com/translations/eVsQcTnbClN-oB7d/docs/images/cdy7uua7fh8z/1ogYIaeDdyGL3Qo511m6Sh/5ab97c1535b2b62523a367594d44d66f/home.png?fit=max&auto=format&n=eVsQcTnbClN-oB7d&q=85&s=5f2f3a899800e2114bfbfdab3540ea4f" alt="アプリケーションのサインインページの例" width="750" height="579" data-path="docs/images/cdy7uua7fh8z/1ogYIaeDdyGL3Qo511m6Sh/5ab97c1535b2b62523a367594d44d66f/home.png" />
   </Frame>
2. Auth0 認可サーバーはユーザーをログインページにリダイレクトし、そこでユーザーは設定済みのログインオプションのいずれかを使って認証します。

   <Frame>
     <img src="https://mintcdn.com/translations/c0RQ9V0YAcT0-8l5/docs/images/cdy7uua7fh8z/6z6aA5nfA1uwOyx8srhvvI/2435a0909cfe44a57bef3ff27ef24e5b/lock.png?fit=max&auto=format&n=c0RQ9V0YAcT0-8l5&q=85&s=bf8ff078e098170e0f46386c8480ddb2" alt="Lock のログインページ" width="750" height="579" data-path="docs/images/cdy7uua7fh8z/6z6aA5nfA1uwOyx8srhvvI/2435a0909cfe44a57bef3ff27ef24e5b/lock.png" />
   </Frame>
3. ユーザーがこのフローを利用するのが初めての場合、SPA に対して Auth0 が付与する権限の一覧を示す同意プロンプトが表示されます。この場合、ユーザーにはアプリが自分の連絡先とカレンダーを読み取ることへの同意が求められます。

   <Frame>
     <img src="https://mintcdn.com/translations/eVsQcTnbClN-oB7d/docs/images/cdy7uua7fh8z/1te4FYRbu0aFcdohdXY2Rv/116bed5515eb2114c39374fb0a258912/consent-screen.png?fit=max&auto=format&n=eVsQcTnbClN-oB7d&q=85&s=0afb59d263e303a00362a72f171ef285" alt="アプリケーションの Lock 同意画面の例" width="750" height="579" data-path="docs/images/cdy7uua7fh8z/1te4FYRbu0aFcdohdXY2Rv/116bed5515eb2114c39374fb0a258912/consent-screen.png" />
   </Frame>
4. ユーザーが同意すると、Auth0 は URI のハッシュフラグメントにトークンを含めてユーザーを SPA にリダイレクトします。これで SPA は JavaScript を使用してハッシュフラグメントからトークンを抽出し、アクセストークンを使用してユーザーに代わって API を呼び出せるようになります。

   ```javascript lines theme={null}
   function getParameterByName(name) {
     var match = RegExp('[#&]' + name + '=([^&]*)').exec(window.location.hash);
     return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
   }

   function getAccessToken() {
     return getParameterByName('access_token');
   }
   ```

   このサンプルでは、ログインに成功すると、論理 API から取得したアクセストークンを使って、いずれかの API を呼び出せるボタンが表示されます。

   <Frame>
     <img src="https://mintcdn.com/translations/Dcx0M11uuptU53TX/docs/images/cdy7uua7fh8z/2pGWG5Wa7U1tBPhAJZ7Bat/7e194066560605cc842f20624b80d958/apis.png?fit=max&auto=format&n=Dcx0M11uuptU53TX&q=85&s=d57abac945d3c484b41a728131c72c2b" alt="ユーザーが認可されたアプリケーション画面の例" width="750" height="579" data-path="docs/images/cdy7uua7fh8z/2pGWG5Wa7U1tBPhAJZ7Bat/7e194066560605cc842f20624b80d958/apis.png" />
   </Frame>

<div id="implement-single-logout-slo-or-single-sign-on-sso">
  ### シングルログアウト (SLO) またはシングルサインオン (SSO) を実装する
</div>

複数のアプリケーションにまたがる一部のシナリオで、シングルログアウトが必要な場合 (あるアプリケーションからログアウトしたユーザーを、他のアプリケーションからもログアウトさせる必要がある場合) は、`checkSession()` を使って定期的に Auth0 をポーリングし、セッションが存在するかどうかを確認するようアプリケーションを設定できます。セッションが存在しない場合は、そのユーザーをアプリケーションからログアウトさせることができます。同じポーリング方法は、<Tooltip tip="Single Sign-On（SSO）: ユーザーが 1 つのアプリケーションにログインすると、そのユーザーは他のアプリケーションにも自動的にログインされるサービス。" cta="用語集を見る" href="/docs/ja-jp/glossary?term=Single+Sign-on">シングルサインオン</Tooltip> (SSO) のシナリオでサイレント認証を実装するためにも使用できます。

今後この呼び出しでレート制限の問題が発生するのを避けるため、`checkSession()` の確認間隔は、呼び出しと呼び出しの間を少なくとも 15 分空けるようにしてください。

<div id="learn-more">
  ## 詳細はこちら
</div>

* [APIを登録する](/docs/ja-jp/get-started/auth0-overview/set-up-apis)
* [API の権限を追加する](/docs/ja-jp/get-started/apis/add-api-permissions)
* [API スコープ](/docs/ja-jp/get-started/apis/scopes/api-scopes)
