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

# カスタムオーソライザーを使用してAWS API Gatewayエンドポイントをセキュリティ保護する

> Auth0発行のアクセストークンを受け入れるカスタムオーソライザーを使用して、安全なAWS API Gatewayを使用する方法。

export const AuthCodeGroup = ({children, dropdown}) => {
  const [processedChildren, setProcessedChildren] = useState(children);
  useEffect(() => {
    let unsubscribe = null;
    function init() {
      unsubscribe = window.autorun(() => {
        const processChildren = node => {
          if (typeof node === "string") {
            let processedNode = node;
            for (const [key, value] of window.rootStore.variableStore.values.entries()) {
              const escapedKey = key.replaceAll(/[.*+?^${}()|[\]\\]/g, (String.raw)`\$&`);
              processedNode = processedNode.replaceAll(new RegExp(escapedKey, "g"), value);
            }
            return processedNode;
          } else if (Array.isArray(node)) {
            return node.map(processChildren);
          } else if (node && node.props && node.props.children) {
            return {
              ...node,
              props: {
                ...node.props,
                children: processChildren(node.props.children)
              }
            };
          }
          return node;
        };
        setProcessedChildren(processChildren(children));
      });
    }
    if (window.rootStore) {
      init();
    } else {
      window.addEventListener("adu:storeReady", init);
    }
    return () => {
      window.removeEventListener("adu:storeReady", init);
      unsubscribe?.();
    };
  }, [children]);
  return <CodeGroup dropdown={dropdown}>{processedChildren}</CodeGroup>;
};

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 = `JWKS_URI="https://{yourDomain}/.well-known/jwks.json"
AUDIENCE="https://your-api-gateway"
TOKEN_ISSUER="https://{yourDomain}/"
`;

AWS Lambda関数（カスタムオーソライザーを含む）を作成・構成してAPIエンドポイントを保護し、認可フローを実装します。これにより、ユーザーはAuth0からAPIへのアクセス取得に必要なアクセストークンを取得できるようになります。

詳細は、[AWS API Gateway](https://aws.amazon.com/api-gateway/)にログインして、「[AWS Lambdaの概要](https://aws.amazon.com/lambda/)」をご覧ください。

API GatewayはLambda関数の前にサービスレイヤーを追加することで、セキュリティを拡張し、入力・出力メッセージの変換を管理し、スロットリングや監査などの機能を提供して、Lambdaの機能を拡張します。サーバーレスアプローチにより、スケールアウトやフォールトトレランスなどの懸念事項がコードを実行するコンピュートサービスの責任となるため、運用上の課題が簡素化されます。

カスタムオーソライザーは以下を行います。

* APIへのアクセス要求の`authorization`ヘッダーを介してアクセストークンが渡されたことを確認する。
* JWKSエンドポイントを介して取得した公開鍵を使用して、アクセストークンのRS256署名を検証する。
* アクセストークンに必要な発行者`iss`とオーディエンス`aud`クレームがあることを確認する。

以下の手順でカスタムオーソライザーを使用します。

1. [Auth0 APIを作成する](#create-an-auth0-api)
2. [AWS API Gateway APIをインポートして導入する](#import-and-deploy-the-aws-api-gateway-api)
3. [カスタムオーソライザーを作成する](#create-the-custom-authorizers)
4. [カスタムオーソライザーを使用してAPIを保護する](#secure-the-api-using-custom-authorizers)
5. [導入をテストする](#test-your-deployment)

署名アルゴリズムの詳細については、「[署名アルゴリズム](/docs/ja-jp/get-started/applications/signing-algorithms)」を参照してください。JWKSの使用に関する詳細は、「[JSON Web Key Sets](/docs/ja-jp/secure/tokens/json-web-tokens/json-web-key-sets)」をご覧ください。

## API Gatewayのカスタムオーソライザーの仕組み

[Amazonによると](http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html)、API Gatewayのカスタムオーソライザーは、「<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-0" href="/docs/ja-jp/glossary?term=oath2" tip="OAuth 2.0: 認可プロトコルとワークフローを定義する認可フレームワーク。" cta="用語集の表示">OAuth</Tooltip>や<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-1" href="/docs/ja-jp/glossary?term=security-assertion-markup-language" tip="Security Assertion Markup Language（SAML）: パスワードなしに二者間で認証情報を交換できる標準化プロトコル。" cta="用語集の表示">SAML</Tooltip>などのベアラートークン認証戦略を使用してAPIへのアクセスを制御するために提供するLambda関数」です。

誰か（または何らかのプログラム）がAPIを呼び出そうとするたびに、API GatewayはそのAPI用に構成されたカスタムオーソライザーがあるかどうかを確認します。

**APIのカスタムオーソライザーがある**場合は、API Gatewayがカスタムオーソライザーを呼び出し、受け取った要求ヘッダーから抽出した認可トークンを提供します。

<Tooltip data-tooltip-id="react-containers-DefinitionTooltip-3" href="/docs/ja-jp/glossary?term=json-web-token" tip="JSON Web Token（JWT）: 二者間のクレームを安全に表現するために使用される標準IDトークン形式（および多くの場合、アクセストークン形式）。" cta="用語集の表示">JWT</Tooltip>検証を含むさまざまなタイプの認可戦略を実装して、要求を認可するIAMポリシーを返すことができます。返されたポリシーが無効か、アクセス許可が拒否された場合は、API呼び出しは失敗です。

ポリシーが有効な場合は、APIが返されたポリシーをキャッシュし、それを受信トークンと関連付けて、現在および後続の要求に使用します。ポリシーがキャッシュされる時間は構成できます。デフォルト値は`300`秒で、キャッシュの最大の長さは`3600`秒です（この値は0に設定してキャッシュを無効化することも可能です）。

詳細は、AmazonのDeveloper Guideにある「[What is Amazon API Gateway?（Amazon API Gatewayとは？）](http://docs.aws.amazon.com/apigateway/latest/developerguide/use-custom-authorizer.html)」を参照してください。JWT検証の詳しい情報は、当社の「[JSON Web Token](/docs/ja-jp/secure/tokens/json-web-tokens)」をお読みください。

## 前提条件

[AWSアカウントにサインアップする](https://portal.aws.amazon.com/gp/aws/developer/registration/index.html)必要があります。これにより、API GatewayとLambdaを含む、AWS機能へのアクセスが付与されます。新規メンバーは全員、12か月無料プランでAWSへのアクセスを得ることができます。

## Auth0 APIを作成する

正常に認可されたアプリケーションによって使用されるAPIを構成します。

1. [［Auth0 Dashboard］>［Applications（アプリケーション）］>［APIs（API）］](https://manage.auth0.com/#/apis)に移動して、\*\*［Create API（APIの作成）］\*\*を選択します。
2. 以下のフィールドに値を入力して、\*\*［Create（作成）］\*\*を選択します。

   | フィールド                                       | 説明                                                                                                                                         |
   | ------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
   | Name（名前）                                    | APIのフレンドリー名。Auth0 APIのリストに表示される名前です。                                                                                                       |
   | Identifier（識別子）                             | APIの一意の識別子。この識別子をURL `https://your-api-gateway`のような形式にすることをお勧めします。                                                                         |
   | JSON Web Token Profile（JSON Webトークンのプロファイル） | OAuth2.0のトークンプロファイルまたはダイアレクト（アクセストークン用）。詳細については、「[アクセストークンのプロファイル](/docs/ja-jp/secure/tokens/access-tokens/access-token-profiles)」をお読みください |
   | 署名アルゴリズム                                    | 発行されたアクセストークンを署名するために、Auth0で使用したいアルゴリズム。詳細については、「[署名アルゴリズム](/docs/ja-jp/get-started/applications/signing-algorithms)」を参照してください。            |

新たに作成されたAPIの詳細を確認するには、\*\*［Settings（設定）］\*\*ビューをご覧ください。

<Frame>
  <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/f9tcsxrYvRYBs4lY/docs/images/ja-jp/cdy7uua7fh8z/4P1N7SSCXUF1SfyC8SXTiO/522a72298a0faf235d24ea43dd790917/Create_API_-_API_Gateway.png?fit=max&auto=format&n=f9tcsxrYvRYBs4lY&q=85&s=bbe64f4ae81e36a8e333a50b2b6179c4" alt="Dashboard - APIの作成 - AWS API Gateway" width="698" height="840" data-path="docs/images/ja-jp/cdy7uua7fh8z/4P1N7SSCXUF1SfyC8SXTiO/522a72298a0faf235d24ea43dd790917/Create_API_-_API_Gateway.png" />
</Frame>

APIを作成すると、APIと共に使用するM2Mアプリケーションも作成されます。このアプリケーションは、\*\*［Machine to Machine Application（M2Mアプリケーション）］**ビューの**［Authorized（認可済み）］\*\*に表示されます。クライアントIDをメモしてください。このチュートリアルのパート3で使用します。

## AWS API Gateway APIをインポートして導入する

<Note>
  チュートリアルのこの部分では、[AWSによる公式の例](http://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-from-example.html)を使用しています。詳しい注意事項や説明については、公式の例を参照してください。
</Note>

この手順では以下を行います。

* APIをAPI Gatewayにインポートする
* APIインポートをテストする
* 任意のフロントエンドアプリケーションで使用できるようにAPIを導入する
* API導入をテストする

### Pets APIをインポートして構成する

1. AWSアカウントにログインし、上部のナビゲーションバーにある\*\*［Services（サービス）］**ドロップダウンから**［API Gateway］\*\*コンソールに移動します。
2. すでにAPIを作成している場合は、API Gatewayコンソールに移動して\*\*［Create API（APIの作成）］**をクリックします。**［Create new API（APIの新規作成）］**フォームで**［Example API（サンプルAPI）］**を作成することもできます。初めてAPI GatewayでAPIを作成する場合は、以下の画面が表示されます。**［Get Started（はじめる）］\*\*をクリックして続けます。

   <Frame>
     <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/itywf6vBRFUC2Nea/docs/images/ja-jp/cdy7uua7fh8z/3MX6jO6ZzTqEWNZaWps0j5/4b97df023e694e452d4f34f03d15d21c/aws-pt1-1.png?fit=max&auto=format&n=itywf6vBRFUC2Nea&q=85&s=00398318d6e0f34dff16bd125d4710b6" alt="AWS API Gateway - Get Started" width="687" height="511" data-path="docs/images/ja-jp/cdy7uua7fh8z/3MX6jO6ZzTqEWNZaWps0j5/4b97df023e694e452d4f34f03d15d21c/aws-pt1-1.png" />
   </Frame>

   API Gatewayに歓迎するポップアップメッセージが表示されます。\*\*［OK］\*\*をクリックして続行します。
3. \*\*［Create new API（APIの新規作成）］**フォームでは、**［Example API（サンプルAPI）］**がデフォルトで選択されており、エディターに定義されたサンプルAPIがあります。本チュートリアルでは以後このAPIを使用するので、**［Import（インポート）］\*\*をクリックしてAPI作成プロセスを開始します。

   <Frame>
     <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/9Vac8_IYDB9MGlmx/docs/images/ja-jp/cdy7uua7fh8z/8b4yGZNUwCNRYovU203Au/d010702b68635ef7e1864554c3a3826f/aws-pt1-4.png?fit=max&auto=format&n=9Vac8_IYDB9MGlmx&q=85&s=2dfbe42235855bbae7c922c5c7957ca1" alt="AWS API Gateway - Example API" width="687" height="512" data-path="docs/images/ja-jp/cdy7uua7fh8z/8b4yGZNUwCNRYovU203Au/d010702b68635ef7e1864554c3a3826f/aws-pt1-4.png" />
   </Frame>

   インポートが終わったら、APIが作成され、提供されたデータが読み込まれたことを示すメッセージが表示されます。APIにはすでにメソッド（`GET`と`POST`）が関連付けられています。リソースツリーでメソッド名をクリックすると、メソッドの詳細表示やその構成の変更、メソッドの呼び出しテストが行えます。

   <Frame>
     <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/1FU_hDyg-ytA7ilg/docs/images/ja-jp/cdy7uua7fh8z/1COXG4sI0DNSM4NIMEtma9/9cc6104e234ac25d1098fd92f1183bc1/aws-pt1-5a.png?fit=max&auto=format&n=1FU_hDyg-ytA7ilg&q=85&s=147e07b96722b1c7bc0598a9048dd542" alt="AWS API Gateway - Resources Tree" width="687" height="511" data-path="docs/images/ja-jp/cdy7uua7fh8z/1COXG4sI0DNSM4NIMEtma9/9cc6104e234ac25d1098fd92f1183bc1/aws-pt1-5a.png" />
   </Frame>

### APIをテストする

APIをテストするには、`/pets`の**POST**をクリックします。すると、\*\*［Method Execution（メソッドの実行）］\*\*画面が表示され、`POST`メソッドの構造と動作の概要を確認できます。

* **［Method Request（メソッド要求）］**と**［Method Response（メソッド応答）］**：APIとフロントエンドのインターフェイス
* **［Integration Request（統合要求）］**と**［Integration Response（統合応答）］**：APIとバックエンドのインターフェイス

この領域を使用してAPIをテストできます。

1. （ページ中程の\*\*［Client（クライアント）］**にある）**［Test（テスト）］**をクリックします。`/pets - POST - Method Test`ページにリダイレクトされます。ページの下までスクロールし、以下のスニペットを**［Request Body（要求本文）］\*\*として入力します。

   ```json lines theme={null}
   {"type": "dog", "price": 249.99}
   ```

   要求本文は、データベースに追加したいペットの属性とそのペットの費用を示します。<Frame><img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/V-g8sIA_dMysRiDH/docs/images/ja-jp/cdy7uua7fh8z/5XKCxyYc5nBCsqln27HVLF/bcd9c16f9e3405fda8cc44f455cb819b/aws-pt1-5d.png?fit=max&auto=format&n=V-g8sIA_dMysRiDH&q=85&s=1c1f1f7ead0ed967aa39e6602d2e7773" alt="AWS API Gateway - Request Body" width="684" height="511" data-path="docs/images/ja-jp/cdy7uua7fh8z/5XKCxyYc5nBCsqln27HVLF/bcd9c16f9e3405fda8cc44f455cb819b/aws-pt1-5d.png" /></Frame>

2. \*\*［Test（テスト）］\*\*をクリックして続行します。ページの右側にテストの結果が表示されます。

   <Frame>
     <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/5l8GTXHD40NsjgmL/docs/images/ja-jp/cdy7uua7fh8z/2cwnpb0irU5DOVKCjcjnil/986f046738bc3b0f79145daa7b86ff3c/aws-pt1-5e.png?fit=max&auto=format&n=5l8GTXHD40NsjgmL&q=85&s=2ec851b11385725ebf4121ba8a40b86d" alt="AWS API Gateway - Test Results" width="685" height="512" data-path="docs/images/ja-jp/cdy7uua7fh8z/2cwnpb0irU5DOVKCjcjnil/986f046738bc3b0f79145daa7b86ff3c/aws-pt1-5e.png" />
   </Frame>

### APIを導入する

先ほど完了したテストは、API Gatewayコンソールを用いて行われました。APIを別のアプリケーションと使用するには、APIをステージに導入する必要があります。

1. \*\*［Actions（アクション）］**メニューで**［Deploy API（APIの導入）］\*\*を選択します。
2. 以下の値を入力して、\*\*［Deploy（導入）］\*\*をクリックします。

   | パラメーター                                 | 値                   |
   | -------------------------------------- | ------------------- |
   | **Deployment stage（導入ステージ）**           | `[New Stage]`を選択    |
   | **Stage name（ステージ名）**                  | ステージの名前を指定します       |
   | **Stage description（ステージの説明）**         | ステージの説明を入力します       |
   | **Deployment description（デプロイメントの説明）** | APIデプロイメントの説明を入力します |

### 導入をテストする

APIが正常に導入されたら、\*\*［Test Stage Editor（テストステージエディター）］\*\*にリダイレクトされます。この時点で、APIが正しく導入されているかをテストすることができます。

1. \*\*［Test Stage Editor（テストステージエディター）］\*\*画面の上部には、\*\*Invoke URL（呼び出しURL）\*\*の青いバナーが表示されます。これは、APIの`GET`エンドポイントを呼び出すために使用するURLです。リンクをクリックしてブラウザーで`GET / method`要求を送信します。これにより、以下のような成功応答が返されるはずです。

   <Frame>
     <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/ZqABYvyPOuGZRvBz/docs/images/ja-jp/cdy7uua7fh8z/7d8340OcAtOF8GvBtihRBt/958eff065c665682ef53b9eedae77a8e/aws-pt1-8.png?fit=max&auto=format&n=ZqABYvyPOuGZRvBz&q=85&s=000ddd4054cc369d82ccaeb6a8e3a4ba" alt="AWS API Gateway - Deploy Test Response" width="684" height="339" data-path="docs/images/ja-jp/cdy7uua7fh8z/7d8340OcAtOF8GvBtihRBt/958eff065c665682ef53b9eedae77a8e/aws-pt1-8.png" />
   </Frame>

2. **［Stages（ステージ）］**ページで、**［Test（テスト）］**のツリーを展開します。`/pets/{petId}`の**GET**をクリックします。

   <Frame>
     <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/5l8GTXHD40NsjgmL/docs/images/ja-jp/cdy7uua7fh8z/2QzVCjIndpP9EQ4VUxVzZc/5c2afef3f8c83004b35636557c9ec59e/aws-pt1-9.png?fit=max&auto=format&n=5l8GTXHD40NsjgmL&q=85&s=7db19970e791916a28b1b7a76a27ff71" alt="AWS API Gateway - Get Pet ID" width="684" height="511" data-path="docs/images/ja-jp/cdy7uua7fh8z/2QzVCjIndpP9EQ4VUxVzZc/5c2afef3f8c83004b35636557c9ec59e/aws-pt1-9.png" />
   </Frame>

3. 画面上部の青いバナーに\*\*Invoke URL（呼び出しURL）\*\*が表示されます。その末尾部分の`{petID}`は、パス変数を表します。この変数を`1`に置き換え、ブラウザーを使って新しいURLに移動します。以下のJSONペイロードのHTTP 200要求を受信するはずです。

   ```json lines theme={null}
   {
     "id": 1,
     "type": "dog",
     "price": 249.99
   }
   ```

## カスタムオーソライザーを作成する

以上の手順で、API Gatewayによって管理された完全に機能するAPIができたので、次に、適切な認可を得たユーザーだけがAPIのバックエンドにアクセスできるようにAPIを保護します。

API Gatewayのカスタム要求オーソライザーを使用して、OAuth 2.0やSAMLなどのベアラートークン認可戦略でAPIを認可します。各受信要求で以下が行われます。

1. API Gatewayが、カスタムオーソライザーが適切に構成されていることを確認します。
2. API Gatewayが、認可トークンを使用してカスタムオーソライザー（Lambda関数）を呼び出します。
3. 認可トークンが有効な場合は、カスタムオーソライザーが適切なAWSのIDおよびアクセス管理（IAM）ポリシーを返します。
4. API Gatewayが、手順3で返されたポリシーを使用して要求を認可します。

### カスタムオーソライザーを準備する

Auth0発行トークンをサポートする[サンプルのカスタムオーソライザーをダウンロード](https://github.com/auth0-samples/jwt-rsa-aws-custom-authorizer)できます。その後、自身の環境でカスタムオーソライザーが動作するようにファイルをカスタマイズする必要があります。

1. ダウンロードしたサンプルファイル入りのフォルダーを任意の場所で解凍し、コマンドラインを使用してフォルダーに移動します。
2. サンプルフォルダー内で`npm install`を実行し、導入に必要なNode.jsパッケージをインストールします。後の手順でAWSにアップロードするバンドルにこれらのファイルを含める必要があります。
3. `.env`ファイルを使ってローカル環境を構成します。`cp .env.sample .env`を使って`.env.sample`ファイルをコピー（すると同時に名前を`.env`に変更）できます。以下の項目を変更します。

   | パラメーター             | 値                                                                                   |
   | ------------------ | ----------------------------------------------------------------------------------- |
   | **`TOKEN_ISSUER`** | トークンの発行者。Auth0がトークン発行者の場合は、`https://{yourDomain}/`を使用する。末尾のスラッシュを必ず付けてください。         |
   | **`JWKS_URI`**     | JWKSエンドポイントのURL。Auth0がトークン発行者の場合は、`https://{yourDomain}/.well-known/jwks.json`を使用する |
   | **`AUDIENCE`**     | 上の「Auth0 APIを作成する」セクションで作成したAPIの**identifier**の値。                                   |

   たとえば、`.env`ファイルのテキストは、完了すると以下のようになります。

   <AuthCodeBlock children={codeExample} language="shell" lines />

### カスタムオーソライザーをローカルでテストする

有効なJWTアクセストークンを取得する取得方法は複数あり、選択する方法はアプリケーションの種類、信頼レベル、または全体的なエンドユーザーのエクスペリエンスに応じます。詳細は、[「アクセストークンを取得する」](/docs/ja-jp/secure/tokens/access-tokens/get-access-tokens)をお読みください。

1. APIのテストトークンを取得するには、[［Auth0 Dashboard］>［Applications（アプリケーション）］>［APIs（API）］](https://manage.auth0.com/#/apis)に移動して、APIを選び、\*\*［Test（テスト）］\*\*を選択します。
2. トークンを含む`event.json`ファイルをローカルに作成します。サンプルファイルをコピーできます（`cp event.json.sample event.json`を実行します）。`ACCESS_TOKEN`を自身のJWTトークンに置き換え、`methodArn`をAPIの`GET`メソッドの適切なARN値に置き換えます。

`methodArn`を取得するには以下を行います。

1. API Gatewayコンソールで\*\*［PetStore］\*\*APIを開きます。
2. 左側のナビゲーションで\*\*［Resources（リソース）］\*\*を選択します。
3. 中央の\*\*［Resources（リソース）］**パネルでリソースツリーを展開します。`/pets`の下の**［GET］\*\*を選択します。
4. \*\*［Method Request（メソッド要求）］**欄に**［ARN］\*\*が表示されます。
5. `npm test`を使用してテストを実行します。

lambda-localパッケージを使用して、トークンを用いてカスタムオーソライザーをテストします。テストに成功すると、以下のように表示されます。

```json lines theme={null}
Message
------
{
    "principalId": "C8npTEMVnBrILsBTI91MOh6dfuZbPVAU@clients",
    "policyDocument": {
        "Version": "2012-10-17",
        "Statement": [
            {
                "Action": "execute-api:Invoke",
                "Effect": "Allow",
                "Resource": "arn:aws:execute-api:us-east-1:1234567890:apiId/stage/method/resourcePath"
            }
        ]
    },
    "context": {
        "scope": "FULL_LIST_OF_SCOPES"
    }
}
```

`Effect`の値が`Allow`の場合は、オーソライザーがAPI Gatewayへの呼び出しを許可していることを表します。

詳細は、NPMの「[Lambda-local](https://www.npmjs.com/package/lambda-local)」を参照してください。

### IAMロールを作成する

IAMロールにはLambda関数を呼び出すために必要なアクセス許可があります。カスタムオーソライザーに取りかかる前に、API Gatewayがアクセス要求を受け取るたびにカスタムオーソライザーを呼び出すことのできるIAMロールを作成する必要があります。

1. AWSにログインし、[［IAM Console（IAMコンソール）］](https://console.aws.amazon.com/iam)に移動します。左側のナビゲーションで\*\*［Roles（ロール）］\*\*を選択します。

2. \*\*［Create new role（ロールの新規作成）］\*\*を選択します。

3. \*\*［AWS service（AWSサービス）］**で**［AWS Lambda］**行を選び、**［Next:Permissions（次へ：アクセス許可）］\*\*を選択します。

4. **［Attach permissions policy（アクセス許可ポリシーのアタッチ）］**画面で、**［AWSLambdaRole］**を選択します。フィルターを使用してオプションのリストを絞り込むことができます。**［Next:Tags（次へ：タグ）］**、\*\*［Next:Review（次へ：確認）］\*\*の順に選択して続行します。

5. \*\*［Review（確認）］**画面で、`Auth0Integration`などの**［Role name（ロール名）］**を入力します。他のフィールドはそのままにします。**［Create role（ロールの作成）］\*\*を選択します。

6. AWSがロールを作成し終えたら、IAMの\*\*［Roles（ロール）］\*\*ページにリダイレクトされます。新しいロールを選択します。

7. 先ほど作成したロールの\*\*［Summary（サマリー）］**ページで**［Trust relationships（信頼関係）］\*\*ビューを選択します。

8. \*\*［Edit trust relationship（信頼関係の編集）］**を選択して、**［Policy Document（ポリシードキュメント）］\*\*フィールドに以下のJSONスニペットを入力します。

   ```json lines theme={null}
   {
      "Version": "2012-10-17",
      "Statement": [
         {
            "Effect": "Allow",
            "Principal": {
               "Service": [
                  "apigateway.amazonaws.com",
                  "lambda.amazonaws.com"
               ]
            },
            "Action": "sts:AssumeRole"
         }
      ]
   }
   ```

9. \*\*［Update Trust Polic（信頼ポリシーの更新）］\*\*をクリックします。

10. \*\*［Summary（サマリー）］**ページにリダイレクトで戻されます。後で使用するために**［Role ARN（ロールARN）］\*\*値をコピーしておきます。

    <Frame>
      <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/5l8GTXHD40NsjgmL/docs/images/ja-jp/cdy7uua7fh8z/1ki5GDOZenh5WRgpbWwzC8/76f415684f08510b4206559032880a59/pt2-10.png?fit=max&auto=format&n=5l8GTXHD40NsjgmL&q=85&s=98cea34c49f8ce5c7ca51dee63d00c5a" alt="undefined" width="686" height="512" data-path="docs/images/ja-jp/cdy7uua7fh8z/1ki5GDOZenh5WRgpbWwzC8/76f415684f08510b4206559032880a59/pt2-10.png" />
    </Frame>

### Lambda関数を作成してカスタムオーソライザーを導入する

以上の手順で、自身の環境用にカスタムオーソライザーを構成し、動作することをテストしたので、次はこれをAWSに導入しましょう。

1. `npm run bundle`を実行して、AWSにアップロードできるバンドルを作成します。これにより、AWS Lambdaが必要とするソース、構成、ノードモジュールを含む`custom-authorizer.zip`バンドルが生成されます。
2. [Lambdaコンソール](https://console.aws.amazon.com/lambda)に移動して、\*\*［Create function（関数の作成）］\*\*をクリックします。
3. \*\*［Select blueprint（ブループリントの選択）］**ページで**［Author from scratch（一から作成）］**をクリックして空の関数を作成します。**［Basic information（基本的な情報）］\*\*で以下のパラメーターの値を入力します。

   | パラメーター              | 値                                      |
   | ------------------- | -------------------------------------- |
   | **Name（名前）**        | Lambda関数の名前。例：`jwtRsaCustomAuthorizer` |
   | **Description（説明）** | Lambda関数の説明（任意）                        |
   | **Runtime（ランタイム）**  | `Node.js 10.x`を選択                      |
4. \*\*［Create Function（関数の作成）］\*\*をクリックして続行します。
5. 関数の\*\*［Configuration（設定）］**ページで**［Function Code（関数コード）］\*\*セクションまで下にスクロールします。
6. \*\*［Code entry type（コード入力タイプ）］**で**［Upload a .ZIP file（.ZIPファイルのアップロード）］\*\*を選択します。
7. \*\*［Upload（アップロード）］\*\*をクリックして、先ほど作成した`custom-authorizer.zip`バンドルを選択します。
8. 次に、以下の3つの\*\*［Environment variables（環境変数）］\*\*を作成します。この情報は`.env`ファイルの情報と同じであることに注意してください。

   | パラメーター             | 値                                                                                   |
   | ------------------ | ----------------------------------------------------------------------------------- |
   | **`TOKEN_ISSUER`** | トークンの発行者。Auth0がトークン発行者の場合は、`https://{yourDomain}/`を使用する                             |
   | **`JWKS_URI`**     | JWKSエンドポイントのURL。Auth0がトークン発行者の場合は、`https://{yourDomain}/.well-known/jwks.json`を使用する |
   | **`AUDIENCE`**     | 手順1で作成したAPIの**identifier**の値。                                                       |
9. \*\*［Execution role（実行ロール）］**セクションで、**［Use an existing role（既存ロールを使用）］**を選択してから、以前**［Existing role（既存ロール）］\*\*として作成したIAMロールを選びます。
10. \*\*［Basic settings（基本設定）］**で**［Timeout（タイムアウト）］**を**［30］\*\*秒に設定します。
11. \*\*［Save（保存）］\*\*をクリックします。
12. 作成したLambda関数をテストするため、右上の\*\*［Test（テスト）］\*\*をクリックします。
13. `event.json`ファイルの内容を\*\*［Configure test event（テストイベントの設定）］\*\*フォームにコピーします。デフォルトの「Hello World」イベントテンプレートを使用できます。
14. \*\*［Create（作成）］\*\*をクリックします。
15. これを選択し、\*\*［Test（テスト）］\*\*をクリックして実行します。テストに成功したら、［Execution result: succeeded（実行結果：成功）］と表示されます。出力画面を展開すると、ローカルテストに成功したときと似たようなメッセージが表示されるはずです。

    <Frame>
      <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/9Vac8_IYDB9MGlmx/docs/images/ja-jp/cdy7uua7fh8z/8Xr9yXq8LwOChAbQkDZlJ/0905bbce96f257716a67376f17a0c975/pt2-19.png?fit=max&auto=format&n=9Vac8_IYDB9MGlmx&q=85&s=dcbe7f8036cd76e3dd50f4b51bb27e9c" alt="undefined" width="686" height="512" data-path="docs/images/ja-jp/cdy7uua7fh8z/8Xr9yXq8LwOChAbQkDZlJ/0905bbce96f257716a67376f17a0c975/pt2-19.png" />
    </Frame>

### API Gatewayのカスタムオーソライザーを構成する

1. API Gatewayコンソールに戻り、先ほど作成した**PetStore** APIを開きます。
2. 左側のナビゲーションから\*\*［Authorizers（オーソライザー）］**を開き、**［Create New Authorizer（オーソライザーの新規作成）］**を選択してから、以下のパラメーターを設定し、**［Create（作成）］\*\*をクリックします。

   | パラメーター               | 値                           |
   | -------------------- | --------------------------- |
   | **名前**               | `jwt-rsa-custom-authorizer` |
   | **タイプ**              | **Lambda**を選択する             |
   | **Lambdaのリージョン**     | 前に作成したLambda関数のリージョンを使用する   |
   | **Lambda関数**         | `jwtRsaCustomAuthorizer`    |
   | **Lambdaの実行ロール**     | 上でコピーしたIAMロールARN            |
   | **Lambdaのイベントペイロード** | \*\*［Token（トークン）］\*\*を選択する  |
   | **トークンのソース**         | `Authorization`             |
   | **トークンの検証**          | `^Bearer [-0-9a-zA-z\.]*$`  |
   | **TTL（秒）**           | `3600`                      |
3. AWSがオーソライザーを作成し、ページが更新されたら、\*\*［Test（テスト）］\*\*をクリックし、先ほど使用したAuth0トークン（`Bearer ey...`）を入力することで、オーソライザーをテストします。テストに成功すると、以下のような応答が表示されます。

   <Frame>
     <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/V-g8sIA_dMysRiDH/docs/images/ja-jp/cdy7uua7fh8z/5lx86XsQEJtxVikZJ4lC2C/c2a5c24a31b9cb4b6540267828bbd3a2/pt2-26.png?fit=max&auto=format&n=V-g8sIA_dMysRiDH&q=85&s=40502f19d75aede9f978aea61d88f200" alt="undefined" width="687" height="513" data-path="docs/images/ja-jp/cdy7uua7fh8z/5lx86XsQEJtxVikZJ4lC2C/c2a5c24a31b9cb4b6540267828bbd3a2/pt2-26.png" />
   </Frame>

## カスタムオーソライザーを使用してAPIを保護する

APIのエンドポイントを保護する方法については、Amazon API GatewayのDeveloper Guideにある、「[Use API Gateway Lambda Authorizers（API Gateway Lambdaオーソライザーを使用する）](https://docs.aws.amazon.com/apigateway/latest/developerguide/apigateway-use-lambda-authorizer.html)」の記事を参照してください。

### カスタムオーソライザーを使用するためにAPI Gatewayリソースを構成する

1. AWSにログインし、[［API Gateway Console（API Gatewayコンソール）］](http://console.aws.amazon.com/apigateway)に移動します。

   <Note>
     カスタムオーソライザーはメソッドごとに設定します。1つのオーソライザーで複数のメソッドを保護したい場合は、メソッドごとに以下の手順を繰り返します。
   </Note>

2. 本チュートリアルの手順2で作成した\*\*［PetStore］\*\* APIを開きます。中央にある\*\*［Resource（リソース）］**ツリーの`/pets`リソースで、**［GET］\*\*メソッドを選択します。

   <Frame>
     <img src="https://mintcdn.com/docs-dev-docs-event-stream-action-templates/itywf6vBRFUC2Nea/docs/images/ja-jp/cdy7uua7fh8z/3Z9Gmy20NDr9Hb9Yk0piXF/0c7572fc188e13106d9340562580e5e0/pt3-2.png?fit=max&auto=format&n=itywf6vBRFUC2Nea&q=85&s=cd8c567fad53ada54a3aa00d926a9e1e" alt="undefined" width="685" height="511" data-path="docs/images/ja-jp/cdy7uua7fh8z/3Z9Gmy20NDr9Hb9Yk0piXF/0c7572fc188e13106d9340562580e5e0/pt3-2.png" />
   </Frame>

3. \*\*［Method Request（メソッド要求）］\*\*を選択します。

4. **［Settings（設定）］**で**［Authorization（認可）］**の右にある**鉛筆**手順3で作成した`jwt-rsa-custom-authorizer`カスタムオーソライザーを選択します。

5. **チェックマーク**アイコンをクリックして、選んだカスタムオーソライザーを保存します。\*\*［API Key Required（APIキーを必須にする）］\*\*フィールドが`false`になっていることを確認します。

### APIを導入する

変更内容を公開するため、APIを導入します。

1. \*\*［Actions（アクション）］**メニューで**［Deploy API（APIの導入）］\*\*を選択します。
2. 以下の値を入力して、\*\*［Deploy（導入）］\*\*をクリックします。

   | パラメーター                                 | 値                   |
   | -------------------------------------- | ------------------- |
   | **Deployment stage（導入ステージ）**           | `[New Stage]`を選択    |
   | **Stage name（ステージ名）**                  | ステージの名前を指定します       |
   | **Stage description（ステージの説明）**         | ステージの説明を入力します       |
   | **Deployment description（デプロイメントの説明）** | APIデプロイメントの説明を入力します |

成功したら、\*\*［Test Stage Editor（テストステージエディター）］**にリダイレクトされます。導入をテストする際に必要になるので、上部の青いバナーに表示されている**Invoke URL（呼び出しURL）\*\*をメモします。

## 導入をテストする

導入をテストするため、先ほどの手順でメモした\*\*Invoke URL（呼び出しURL）\*\*に`GET`呼び出しを行います。このテストに失敗した場合は、JWTアクセストークンを正しく取得していることを確認してください。

詳細は、「[アクセストークンを取得する](/docs/ja-jp/secure/tokens/access-tokens/get-access-tokens)」でご覧ください。

<AuthCodeGroup>
  ```bash cURL lines theme={null}
  curl --request GET \
  --url https://%7ByourInvokeUrl%7D/pets
  ```

  ```csharp C# lines theme={null}
  var client = new RestClient("https://%7ByourInvokeUrl%7D/pets");
  var request = new RestRequest(Method.GET);
  IRestResponse response = client.Execute(request);
  ```

  ```go Go lines theme={null}
  package main
  import (
  "fmt"
  "net/http"
  "io/ioutil"
  )
  func main() {
  url := "https://%7ByourInvokeUrl%7D/pets"
  req, _ := http.NewRequest("GET", url, nil)
  res, _ := http.DefaultClient.Do(req)
  defer res.Body.Close()
  body, _ := ioutil.ReadAll(res.Body)
  fmt.Println(res)
  fmt.Println(string(body))
  }
  ```

  ```java Java lines theme={null}
  HttpResponse response = Unirest.get("https://%7ByourInvokeUrl%7D/pets")
  .asString();
  ```

  ```javascript Node.JS lines theme={null}
  var axios = require("axios").default;
  var options = {method: 'GET', url: 'https://%7ByourInvokeUrl%7D/pets'};
  axios.request(options).then(function (response) {
  console.log(response.data);
  }).catch(function (error) {
  console.error(error);
  });
  ```

  ```objc Obj-C lines theme={null}
  #import 
  NSMutableURLRequest \*request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://%7ByourInvokeUrl%7D/pets"]
  cachePolicy:NSURLRequestUseProtocolCachePolicy
  timeoutInterval:10.0];
  [request setHTTPMethod:@"GET"];
  NSURLSession \*session = [NSURLSession sharedSession];
  NSURLSessionDataTask \*dataTask = [session dataTaskWithRequest:request
  completionHandler:^(NSData \*data, NSURLResponse \*response, NSError \*error) {
  if (error) {
  NSLog(@"%@", error);
  } else {
  NSHTTPURLResponse \*httpResponse = (NSHTTPURLResponse \*) response;
  NSLog(@"%@", httpResponse);
  }
  }];
  [dataTask resume];
  ```

  ```php PHP lines theme={null}
  $curl = curl_init();
  curl_setopt_array($curl, [
  CURLOPT_URL => "https://%7ByourInvokeUrl%7D/pets",
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => "",
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 30,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => "GET",
  ]);
  $response = curl_exec($curl);
  $err = curl_error($curl);
  curl_close($curl);
  if ($err) {
  echo "cURL Error #:" . $err;
  } else {
  echo $response;
  }
  ```

  ```python Python lines theme={null}
  import http.client
  conn = http.client.HTTPSConnection("")
  conn.request("GET", "%7ByourInvokeUrl%7D/pets")
  res = conn.getresponse()
  data = res.read()
  print(data.decode("utf-8"))
  ```

  ```ruby Ruby lines theme={null}
  require 'uri'
  require 'net/http'
  require 'openssl'
  url = URI("https://%7ByourInvokeUrl%7D/pets")
  http = Net::HTTP.new(url.host, url.port)
  http.use_ssl = true
  http.verify_mode = OpenSSL::SSL::VERIFY_NONE
  request = Net::HTTP::Get.new(url)
  response = http.request(request)
  puts response.read_body
  ```

  ```swift Swift lines theme={null}
  import Foundation
  let request = NSMutableURLRequest(url: NSURL(string: "https://%7ByourInvokeUrl%7D/pets")! as URL,
  cachePolicy: .useProtocolCachePolicy,
  timeoutInterval: 10.0)
  request.httpMethod = "GET"
  let session = URLSession.shared
  let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
  print(error)
  } else {
  let httpResponse = response as? HTTPURLResponse
  print(httpResponse)
  }
  })
  dataTask.resume()
  ```
</AuthCodeGroup>
