我想在 Amazon API Gateway、AWS Lambda 授权方和后端服务之间传递数据。此外,我想解决授权者的请求数据访问限制。
解决方法
**注意:**确保已启用包含数据跟踪的 Amazon CloudWatch 执行日志。此外,在更改集成或映射模板后部署您的 API。
在 API Gateway 中创建 Lambda 授权方
**先决条件:**创建 Lambda 函数。有关 Python 的说明,请参阅使用 Python 构建 Lambda 函数。有关 Node.js 的说明,请参阅使用 Node.js 构建 Lambda 函数。
创建 REQUEST 类型的 Lambda 授权方。对于 Identity source type(身份来源类型),请确保将其保留为 Header(标头)。对于 Key(键),输入键的名称,例如 Authorizationtoken。
配置 Lambda 授权方并访问请求正文
请求授权方仅能访问标头、查询参数、阶段变量和上下文变量。在 API Gateway 中,请求正文数据不会传递给授权方函数。要访问请求正文,请配置 Lambda 授权方,并使用 HTTP 标头或查询字符串参数来发送授权所需的数据。
完成以下步骤:
-
打开 API Gateway 控制台。
-
选择您的 API,然后选择您的资源。
-
在 Methods(方法)下,选择您的方法,然后配置您的 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,然后选择您的资源。
-
在 Methods(方法)下,选择您的方法,然后选择 Integration request(集成请求)。
-
在 Mapping templates(映射模板)下,添加 content-type: application/json,然后输入以下模板:
{
"body": $input.json('$'),
"authorizer-context": {
"context-key": "$context.authorizer.context-key"
}
}
**注意:**请将 context-key 替换为所需的上下文键的名称。
使用代理集成的 HTTP 集成
如果使用代理集成,则必须在集成请求中使用标头或查询字符串参数来包含上下文信息。
完成以下步骤:
- 打开 API Gateway 控制台。
- 选择您的 API,然后选择您的资源。
- 在 Methods(方法)下,选择您的方法。
- 选择 Integration request(集成请求),然后选择 Edit(编辑)。
- 在 URL query string parameters(URL 查询字符串参数)下,选择 Add query string parameter(添加查询字符串参数)。
- 对于 Name(名称),输入 header-with-context-information。
- 对于 Mapped from(映射自),输入 context.authorizer.context-key。<br id=hardline_break/>
**注意:**请将 context-key 替换为您上下文键的名称。
- 选择 Save(保存)。
您的 HTTP 后端将根据您在集成中添加上下文信息的部分,将此信息添加到标头或查询字符串参数中。
使用非代理集成的 HTTP 集成
如果使用非代理集成,则必须添加标头或查询字符串参数。或者使用映射模板。有关如何添加标头或查询字符串参数的说明,请参阅本文的配置 Lambda 授权方并访问请求正文部分。有关如何使用映射模板的说明,请参阅本文的使用非代理集成的 Lambda 函数部分。