> ## 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) + "*****マスク済み*****";
          }
          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 のサービスを設定するための主要な製品。" cta="用語集を見る" href="/ja/docs/glossary?term=Auth0+Dashboard">Auth0 Dashboard</Tooltip> で 1 つの論理 API として表現することで、認可プロセスを簡素化できます。こうすることで、実装する <Tooltip tip="Auth0 のサービスを設定するための主要な製品。" cta="用語集を見る" href="/ja/docs/glossary?term=authorization+flow">認可フロー</Tooltip> は 1 つで済み、適切なスコープを割り当てることで各 API へのアクセスも引き続き制御できます。

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

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

2 つの API は、`Organizer Service` という 1 つの Auth0 API で表現します。次に 2 つのスコープを作成し、SPA から `calendar` API と `contacts` API にアクセスするために [Implicit Flow](/ja/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) をどのように使用できるかを示します。

次の手順を完了してください。

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

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

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

  * **Application Type** で **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>

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

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

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

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

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

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

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

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

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

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

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

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

* **マシン間アプリケーション**がある場合は、[Client Credentials フロー](/ja/docs/get-started/authentication-and-authorization-flow/client-credentials-flow) を実行することで、そのアプリケーションが API のアクセストークンをリクエストできるように認可できます。
* **ネイティブアプリ**を構築している場合は、[PKCE を使用する認可コードフロー](/ja/docs/get-started/authentication-and-authorization-flow/authorization-code-flow-with-pkce) を実装できます。

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

1. ユーザーが SPA 内で Login をクリックすると、アプリケーションはユーザーを Auth0 認可サーバー (`/authorize` エンドポイント) にリダイレクトします。この呼び出しのパラメーターについて詳しくは、チュートリアル「[Call Your API Using the Authorization Code Flow with PKCE](/ja/docs/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. ユーザーがこのフローを利用するのが初めての場合、Auth0 が SPA に付与する権限の一覧を表示する同意プロンプトが表示されます。この場合、ユーザーはアプリケーションが自分の連絡先とカレンダーを読み取ることに同意するよう求められます。

   <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 Consent 画面の例" 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>

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

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

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

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