AWS API 方法因 504 错误而失败;使用 Cognito 和 CORS

Rya*_*bbs 2 ajax jquery amazon-web-services cors

概括:

我将进入下面的杂草,但基本上我的最终目标是从 AWS Lambda 函数检索值并将其返回到我的页面的客户端。该页面使用 AWS Cognito 对用户进行身份验证,并在通过身份验证后发布到 API 网关端点以从我的 Lambda 函数(Lambda 查询 DynamoDB)检索数据。这是我正在努力解决的部分,因为我收到了 504(超时)错误。

我知道我的 Lambda 正确返回值,并且我的 API 理论上实现正确,或者至少它在 API 网关管理控制台的测试部分工作。

细节:

我花了很多时间试图找出我的错误所在,我相信这与 Cognito 身份验证或 CORS 有关。如果我从我的 API 网关方法中删除授权要求并且不发送授权令牌,那么我会从帖子中得到预期的响应。这让我相信我的问题的根源可能是在 Post 方法上错误地实现了 Cognito 授权。

我使用 CORS 是因为该站点托管在 EC2 上,但其 RESTful 路由使用 AWS API Gateway。

此外,我使用 Cognito javascript SDK 对用户进行身份验证,然后将 authToken 传递到我的 ajax 中的自定义标头中。

这是我的 ajax:

$.ajax({
    method: 'POST',
    url: _config.api.invokeUrl + '/getusersites',
    dataType: "json",
    crossDomain: true,
    cors: true,            
    xhrFields: {
        withCredentials: true
    },
    headers: {
        Authorization: token
    },            
    data: JSON.stringify(user),
    success: completeRequest,            
    error: ajaxError  
});
Run Code Online (Sandbox Code Playgroud)

现在,除非我误解了,当我查看 Chrome 开发工具的网络选项卡中的标题时,似乎该帖子在预检中失败了。因为当我查看该 URL 的 General 部分时,它说:

请求方法:OPTIONS

状态码:504

(有关完整标题,请参阅下面的更新)

身体是:

{"message": "端点请求超时"}

所以这会让我相信 CORS 的 Option 请求在 Post 被调用之前就超时了。

我也收到控制台错误:

加载失败(此处为我的 API 端点):对预检请求的响应未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。Origin ' (My origin domain) ' 因此不允许访问。响应具有 HTTP 状态代码 504。

所以对我来说,看起来 CORS 预检在 API 超时之前没有响应。

我没有在 API 资源上的 Options 方法的方法执行中启用授权,但我为 Post 方法启用了授权。正如我之前所说,如果我禁用它,那么一切都会按预期工作,只是没有 Cognito 授权检查。

那么我在这里做错了什么?这是CORS问题吗?授权问题?两个都?

我试过的:

我试图将 CORS 标头添加到我的 Post 方法的集成响应中。但是,我相信这并没有什么区别,因为它们只会返回 200(成功)代码,而我得到的是 504 代码。

我想我的 Lambda 函数或 Cognito 用户池的授权方可能存在权限问题。所以我进入了 IAM 并给了他们他们可能想要的所有权限。这并没有改变结果。

我在我的 ajax 可能设置不正确的理论下工作,所以我尝试了几种不同的方法来实现帖子的参数,但是唯一有效的方法是如果我禁用授权并且不发送自定义标头使用身份验证令牌。

我确保我的 API 资源已启用 CORS 并已重新部署。要是这么简单就好了。

我已经搜索了足够多的谷歌服务器,但我无法提出这个问题。

最后的想法:

如果您愿意花时间阅读我的小说,我将不胜感激。如果有人尝试做类似的事情或对方向有任何想法,我可以继续讨论这个问题。我仍在学习如何处理所有这些 AWS 实施,所以我确定我只是在某个地方犯了一些愚蠢的错误。

预先感谢您的回复。

>>>更新:<<<

每个请求,这里是 OPTION 尝试的完整标头。由于 OPTION 尝试出现 504 错误,因此没有 POST。

一般的:

请求 URL:https:// (API 端点) .amazonaws.com/prod/getusersites

请求方法:OPTIONS

状态码:504

远程地址:52.84.11.37:443

推荐人政策:降级时不推荐人

响应头:

内容长度:41

内容类型:应用程序/json

日期:2018 年 4 月 4 日,星期三 16:16:14 GMT

状态:504

通过:1.1 0a9f4502819b08c3a7919c963887be2b.cloudfront.net(CloudFront)

x-amz-apigw-id: E0wHvE3doAMFgrA=

x-amz-cf-id: pVgd6gNNtw-cYxKe4s9jdEnfU2rBle8cd9MyP34aduYi0_ds4YBRCA==

x-amzn-requestid: 6e014d82-3823-11e8-bc41-3f13ca287d3c

x-cache:来自 cloudfront 的错误

请求头:

:authority: (API 端点)

:方法:选项

:路径:/prod/getusersites

:方案:https

接受:/

接受编码:gzip、deflate、br

接受语言:en-US,en;q=0.9

访问控制请求头:授权

访问控制请求方法:POST

缓存控制:无缓存

来源:https:// (来源域)

pragma: 无缓存

用户代理:Mozilla/5.0(Windows NT 10.0;Win64;x64)AppleWebKit/537.36(KHTML,如 Gecko)Chrome/65.0.3325.181 Safari/537.36

Rya*_*bbs 8

它花了很长时间,但我终于弄清楚出了什么问题。

问题是当我通过 AWS API 网关控制台实施 CORS 时,AWS 如何设置 OPTIONS 集成请求。

默认情况下,它将集成请求设置为 HTTP,使用 API 调用 URL 作为端点。出于某种原因,这导致 OPTIONS 预检超时并以 504 响应。仍然不知道为什么,可能与身份验证有关。

解决方案:

在我的 OPTIONS 方法的集成请求部分,我将集成类型从 HTTP 更改为 MOCK。

然后,在保存之后,我必须转到我的 OPTIONS 方法的集成响应部分,展开 200 HTTP 状态代码,展开标题映射并重新输入我的标题的值。标题仍然存在,但值已被删除。我的最终响应标头如下所示:

Access-Control-Allow-Headers 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'

访问控制允许来源的“https:// MyDomain.com

Access-Control-Allow-Credentials 'true'

Access-Control-Allow-Methods 'DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT'

设置完这些之后,我重新部署了 API,它运行得很好!现在我要去喝一瓶香槟了。:)