jquery - AWS API 方法失败并出现 504 错误;使用 Cognito 和 CORS

标签 jquery ajax amazon-web-services cors

摘要:

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

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

详情:

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

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

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

这是我的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  
});

现在,除非我有误解,否则当我查看 Chrome 的 DevTools 的“网络”选项卡中的标题时,似乎该帖子在预检时失败了。因为当我查看那个 URL 的 General 部分时,它说:

Request Method: OPTIONS

Status Code: 504



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

body 是:

{"message": "Endpoint request timed out"}



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

我也收到控制台错误:

Failed to load (My API endpoint here): Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin '(My origin domain)' is therefore not allowed access. The response had HTTP status code 504.



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

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

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

我试过的:

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

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

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

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

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

最后的想法:

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

预先感谢您的回复。

>>>更新:<<<

根据请求,这里是 OPTION 尝试的完整 header 。由于 OPTION 尝试出现 504 错误,因此没有 POST。

一般的:

Request URL: https://(API endpoint).amazonaws.com/prod/getusersites

Request Method: OPTIONS

Status Code: 504

Remote Address: 52.84.11.37:443

Referrer Policy: no-referrer-when-downgrade



响应 header :

content-length: 41

content-type: application/json

date: Wed, 04 Apr 2018 16:16:14 GMT

status: 504

via: 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: Error from cloudfront



请求 header :

:authority: (API Endpoint)

:method: OPTIONS

:path: /prod/getusersites

:scheme: https

accept: /

accept-encoding: gzip, deflate, br

accept-language: en-US,en;q=0.9

access-control-request-headers: authorization

access-control-request-method: POST

cache-control: no-cache

origin: https://(Origin Domain)

pragma: no-cache

user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36

最佳答案

一直用了很久,但我终于弄清楚出了什么问题。
问题是当我通过 AWS API Gateway 控制台实现 CORS 时,AWS 如何设置 OPTIONS 集成请求。
默认情况下,它将集成请求设置为 HTTP,使用 API 调用 URL 作为端点。出于某种原因,这导致 OPTIONS 预检超时并以 504 响应。仍然不知道为什么,可能与身份验证有关。
解决方案:
在我的 OPTIONS 方法的集成请求部分,我将集成类型从 HTTP 更改为 MOCK。
然后,保存之后,我必须转到 OPTIONS 方法的集成响应部分,展开 200 HTTP 状态代码,展开 header 映射并重新输入我的 header 的值。标题仍然存在,但值已被删除。我的最终响应标题如下所示:

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

Access-Control-Allow-Origin 'https://MyDomain.com'

Access-Control-Allow-Credentials 'true'

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


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

关于jquery - AWS API 方法失败并出现 504 错误;使用 Cognito 和 CORS,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49640351/

相关文章:

ajax - asp ModalPopupExtender 加载一个完整的新网站?

amazon-web-services - 如何下载kms加密的s3对象

php - 在 Laravel 5 中验证动态添加的输入字段

javascript - 在ajax请求中传递对象

javascript - 在 Ruby on Rails 中将 Select Option 表单与 If 语句结合使用

javascript - 如何使用javascript或jquery设置listview中hiddenfield的值

php - 使用 Amazon RDS 查询大型 MySQL 表

node.js - 使用 nodeJs 和 AWS 调整图像大小

javascript - 通过 Javascript 获取 Facebook 公开照片的点赞数 - 可能吗?

javascript - 如何在jquery中比较两个格式为 "dd-mm-yyyy hh:mm"的日期