Amazon API Gateway、AWS Lambda オーソライザー、バックエンドサービス間でデータを渡したいと考えています。また、オーソライザーにおけるリクエストデータのアクセス制限にも対処したいです。
解決策
注: データトレースを含む Amazon CloudWatch 実行ログを有効にしてください。また、統合テンプレートまたはマッピングテンプレートを変更した後に API をデプロイしてください。
API Gateway で Lambda オーソライザーを作成する
前提条件: Lambda 関数を作成します。Python の手順については、「Python による Lambda 関数の構築」を参照してください。Node.js の手順については、「Node.js による Lambda 関数の構築」を参照してください。
REQUEST Lambda オーソライザーを作成します。[ID ソースタイプ] については、必ず [ヘッダー] のままにしてください。[キー] には、Authorizationtoken などキーの名前を入力します。
Lambda オーソライザーを設定してリクエスト本文にアクセスする
リクエストオーソライザーは、ヘッダー、クエリパラメータ、ステージ変数、コンテキスト変数にのみアクセスできます。API Gateway では、リクエスト本文のデータはオーソライザー関数に渡されません。リクエスト本文にアクセスするには、Lambda オーソライザーを設定し、HTTP ヘッダーまたはクエリ文字列パラメータを使用して認証に必要なデータを送信します。
次の手順を実行します。
-
API Gateway コンソールを開きます。
-
ご使用の API を選択し、リソースを選択します。
-
[メソッド] でメソッドを選択し、Lambda オーソライザーを設定します。<br id=hardline_break/>
注: オーソライザーを設定するときは、ヘッダー名を小文字にする必要があります。
-
Lambda オーソライザーのコード例
exports.handler = async (event) => {
console.log('Authorizer event:', JSON.stringify(event, null, 2));
const headers = event.headers || {};
const queryParams = event.queryStringParameters || {};
const requestContext = event.requestContext || {};
evaluation_logic_returned_policy
return {
principalId: 'user',
policyDocument: {
Version: '2012-10-17',
Statement: [{
Action: 'execute-api:Invoke',
Effect: 'Allow',
Resource: event.methodArn
}]
},
context: {
userId: '123',
headerData: headers['validation-data-via-header'] || 'no-header-data',
queryData: queryParams.validationData || 'no-query-data',
contextresourcePath: requestContext.resourcePath || 'no-context-resource-path'
}
};
};
注: サンプルコードは、ヘッダーとクエリパラメータを介して送信されたクライアントデータにアクセスできるオーソライザーを示しています。オーソライザーはクライアントデータを使用してアクセス認可を評価します。また、サンプルコードではすべてのリクエストを許可しています。別のポリシーを返すには、evaluation_logic_returned_policy を実際の評価ロジックに置き換えてください。
-
次のコマンドを実行して API に情報を送信し、オーソライザーのアクセスをテストします。
curl -i -X POST "https://api-id.execute-api.region.amazonaws.com/stage_name/resource_path?validationData=test-query-value" \
-H "Authorizationtoken: allow" -H "Validation-Data-Via-Header: test-header-value" \
-H "Content-Type: application/json" \
--data '{"test":"data"}'
注: api-id をご使用の API ID に、region を AWS リージョンに、stage_name を API ステージ名に、resource_path を API のパスにそれぞれ置き換えます。また、キーに別の名前を入力した場合は、Authorizationtoken をご使用のキーの名前に置き換えてください。
-
Lambda 関数または API Gateway のログをチェックして、オーソライザーがアクセスできることを確認します。
詳細については、「API Gateway Lambda オーソライザーからの出力」を参照してください。
Lambda または HTTP 統合を使用してバックエンドサービスのコンテキストにアクセスする
オーソライザーがコンテキスト情報を返しても、バックエンドサービスのコンテキスト情報にアクセスできない場合があります。アクセスできない場合は、バックエンドとして Lambda または HTTP 統合を使用する必要があります。
プロキシ統合で Lambda 関数を使用する
プロキシ統合で Lambda 関数を使用する場合、Lambda 関数が取得するイベントによってコンテキストデータが自動的に追加されます。
イベントログの例
{
"httpMethod": "POST",
"headers": {
...
},
...
"requestContext": {
"resourceId": "o8nevr",
"authorizer": {
"principalId": "user",
"integrationLatency": 348,
},
...
},
"body": "{\"test\":\"data\"}",
...
}
非プロキシ統合で Lambda 関数を使用する
非プロキシ統合で Lambda 関数を使用する場合は、マッピングテンプレートを使用する必要があります。マッピングテンプレートには、Lambda 関数に送信されるペイロードにコンテキスト情報が含まれます。
マッピングテンプレートを使用するには、次の手順を実行します。
-
API Gateway コンソールを開きます。
-
ご使用の API を選択し、リソースを選択します。
-
[メソッド] でメソッドを選択し、[統合リクエスト] を選択します。
-
[マッピングテンプレート] に content-type: application/json を追加し、次のテンプレートを入力します。
{
"body": $input.json('$'),
"authorizer-context": {
"context-key": "$context.authorizer.context-key"
}
}
注: context-key は、希望するコンテキストキーの名前に置き換えてください。
プロキシ統合で HTTP 統合を使用する
プロキシ統合を使用する場合は、統合リクエストでヘッダーまたはクエリ文字列パラメータを使用してコンテキスト情報を含める必要があります。
次の手順を実行します。
- API Gateway コンソールを開きます。
- ご使用の API を選択し、リソースを選択します。
- [メソッド] で、メソッドを選択します。
- [統合リクエスト] を選択し、[編集] を選択します。
- [URL クエリ文字列パラメータ] で、[クエリ文字列パラメータの追加] を選択します。
- [名前] に header-with-context-information を入力します。
- [マッピング元] に context.authorizer.context-key を入力します。<br id=hardline_break/>
注: context-key をご使用のコンテキストキーの名前に置き換えてください。
- [保存] を選択します。
HTTP バックエンドは、統合内でコンテキスト情報を追加したセクションに基づいて、ヘッダーまたはクエリ文字列パラメータにコンテキスト情報を追加します。
非プロキシ統合で HTTP 統合を使用する
非プロキシ統合を使用する場合は、ヘッダーまたはクエリ文字列パラメータを追加する必要があります。または、マッピングテンプレートを使用してください。ヘッダーまたはクエリ文字列パラメータを追加する方法については、本記事の「Lambda オーソライザーを設定してリクエスト本文にアクセスする」セクションを参照してください。マッピングテンプレートの使用方法については、本記事の「非プロキシ統合で Lambda 関数を使用する」セクションを参照してください。