我有一个运行 AWS ECR 上托管的 Docker 容器的 AWS Lambda 函数。该容器包含一个充当我的后端的 Python FastAPI 服务器。该项目的最终目标是让 CloudFront 发行版与 lambda 后端进行通信。
在 lambda 函数前面,我已经配置了带有 lambda 代理集成的 AWS API Gateway (REST API)。对于这一部分,我基本上遵循了本教程。我有一个“测试阶段”阶段,其中有一个“健康测试”资源,该资源有一个“ANY”方法,通过代理将请求重定向到正确的 Lambda 函数。我没有为此激活任何授权或请求验证设置。
我面临的问题是,无论是在 API Gateway 控制台“测试”选项卡上还是使用 Postman,我得到的响应都是
"detail": "Not Found"
(对于 URL https://****h8fi93.execute-api.eu-west-3.amazonaws.com/test-stage/health-test
)和 "message": "Missing Authentication Token"
(对于任何更长的 URL,例如 https://****h8fi93.execute-api.eu-west-3.amazonaws.com/test-stage/health-test/pros/all
(这对应于我的 API 的实际路线)。
我已经验证 lambda 函数指向正确的 ECR 容器。我已经验证了lambda函数有一个与API网关对应的触发器,如下所示:
我尝试在 FastAPI 端和 API Gateway 控制台上启用和禁用 CORS,但没有成功。我尝试了 GET 和 POST 请求,但没有成功。可能值得注意的是,在给 lambda 一些时间关闭后,测试请求确实会触发 lambda 函数(CloudWatch 日志证实了这一点),因此确实发生了通信。
SO 上的其他类似问题已找到答案,但没有一个符合我的情况(例如here或here)。
cURL 表示此错误响应标头:
x-amzn-errortype: MissingAuthenticationTokenException
为正文 {"message":"Missing Authentication Token"}
。
我是否错过了一些明显的事情,或者有什么我对此没有做对的事情?
TL;博士
https://****h8fi93.execute-api.eu-west-3.amazonaws.com/test-stage/health-test
不起作用,因为资源“健康测试”与我的 Lambda 后端中的任何实际端点都不匹配。调整资源/方法,使它们与可用端点匹配可以解决我的问题。
此外,代理资源和 Lambda 代理集成不是一回事,前者将所有请求转发到您为定义的“ANY”方法选择的任何集成,后者指的是完全传递到您的集成的请求/响应。
长版:
对于任何可能对 API Gateway / Lambda 和代理工作方式感到困惑的人,以下是我解决问题的方法以及我希望首先理解的内容:
创建 API Gateway REST API 时,您创建的“资源”应与 Lambda 运行的代码中的实际 API 路径相对应。 “阶段”的情况并非如此,因此您可以将阶段命名为任何您想要的名称,它只会更改调用 URL(可能还更改更高级的内容)。
https://****h8fi93.execute-api.eu-west-3.amazonaws.com/test-stage/health-test
给我一个 "detail": "Not Found"
是正常的,因为我的 FastAPI 代码中没有 health-test
路线。
从这一点来看,似乎有两个选择,至少就我而言:
如果您需要控制将哪些请求和哪些 HTTP 方法转发到哪些 API 端点(可能在多个 lambda 或其他服务上),请根据您的后端结构声明资源和子资源。对于每个资源,声明控制请求转发的方法。
如果您想将所有请求/方法直接转发到 lambda 函数,声明代理资源就可以了。在我的例子中,资源路径是“/”,资源名称是{proxy+},但允许使用子级代理资源。
创建代理资源以将具有“ANY”方法的所有请求转发到我的 Lambda 代理集成允许我从方法的“测试”选项卡或通过 Postman 从我的实际 API 路由获取预期响应(使用在测试选项卡中,在“代理”字段中添加端点路径,或留空以到达根端点)。
部署 API Gateway API 后,可能会在需要时启用 CORS,并仔细检查 Lambda 触发器是否已正确设置,端点应该可以访问。