10

我正在使用 Amplify,并让我的 API 网关代理到 Lambda。我已经在我的服务器上启用了 CORS/{proxy+}并部署了 API。在我的 Lambda 函数中,我在我的普通函数中设置了适当的标头:

import json


def handler(event, context):
    print("received event:")
    print(event)
    return {
        "statusCode": 200,
        "headers": {
            "Access-Control-Allow-Credentials": True,
            "Access-Control-Allow-Headers": "Content-Type",
            "Access-Control-Allow-Methods": "OPTIONS,POST,GET",
            "Access-Control-Allow-Origin": "*",
        },
        "body": json.dumps(event),
    }

此 Lambda 函数位于通过 Cognito 进行身份验证的 API Gateway 资源后面。

当我使用 Amplify 调用我的 API 时:

let myInit = {
          headers: {
            Authorization: `Bearer ${(await Auth.currentSession())
              .getIdToken()
              .getJwtToken()}`
          }
        }; 

API.get("adminapi", "/admin", myInit) ...

我的GET请求中缺少可怕的 CORS 标头“Access-Control-Allow-Origin”:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://xxxxxxxxxx.execute-api.us-east-1.amazonaws.com/dev/admin. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing).

我看到它在OPTIONS请求中返回:

在此处输入图像描述

我什至在 Postman 中进行了测试以验证标题是否回来了:

在此处输入图像描述

我在这里做错了什么?调用似乎没有通过 API 网关。我想知道它是否与身份验证有关。当我使用我的 IAM 凭证从 Postman 进行测试时,它可以正常工作,但是从我的 Web 应用程序使用不记名令牌时,它会像上面一样失败。

4

5 回答 5

1

我刚刚为类似的事情而苦苦挣扎。这里的问题询问为什么浏览器在使用 Amplify 访问 API 网关时返回 CORS 错误,尽管在端点中正确配置了 CORS 标头。

除了不正确的 CORS 标头配置之外,如果请求的某些方面不正确,Amplify / API Gateway 会给出 CORS 错误。我遇到的有:

  • 您使用的 HTTP 谓词不存在于端点
  • 您使用的端点不存在(例如错字)
  • Content-Type 标头不正确

后者给我带来了问题。似乎Amplify.API.post两者都默认Amplify.API.put发送 Content-Type application/x-www-form-urlencoded。我的 API 是预期application/json的,结果是 CORS 错误。

于 2021-07-21T23:15:48.670 回答
0

在我使用 Amplify 并试图保护 API 网关时,我刚刚遇到了同样的问题,只有通过 Cognito 登录的用户才能访问。

我错过的您可能也错过的步骤是 AWS API-Gateway 中的一些配置。您需要转到网关仪表板并创建一个使用您的 Cognito 用户池的“授权者”。这token source将是您为此使用的任何标题标签(通常是“授权”)。

创建新的授权人

但你还没有完成。然后,您需要转到“资源”并更改方法请求以使用您刚刚创建的新授权方。

将新的授权方与资源一起使用

希望在做完这一切之后,你应该会没事的。如果您的用户已登录,并且您像以前一样添加 Authorization 标头:

let myInit = {
          headers: {
            Authorization: `Bearer ${(await Auth.currentSession())
              .getIdToken()
              .getJwtToken()}`
          }
        };

然后希望一切顺利。

可以在 Youtube 上找到显示这些步骤的视频指南,从 10:50 左右开始

于 2021-12-06T22:03:14.927 回答
0

我遇到了同样的问题。我的飞行前OPTIONS请求具有所有正确的标题:

access-control-allow-headers: Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent
access-control-allow-methods: DELETE,GET,HEAD,OPTIONS,PATCH,POST,PUT
access-control-allow-origin: *

所以我添加后浏览器开始接受请求

access-control-allow-origin: *

对我想使用的实际方法的请求的响应(非预检,例如:GET,POST等方法)

于 2020-12-06T17:16:42.957 回答
0

在 js 中使用fetch()时,当我从我的 API Gateway OPTIONS 端点中删除 Cognito 身份验证时,它起作用了。Chrome 和 Firefox 不会将 Authorize 标头发送到 OPTIONS。不过,放大可能会有所不同。引用:https ://fetch.spec.whatwg.org/#http-responses ...

"For a CORS-preflight request, request’s credentials mode is always "same-origin", i.e., it excludes credentials, but for any subsequent CORS requests it might not be."
于 2021-03-09T11:52:24.370 回答
0

我假设您忘记处理OPTIONS用于预检请求的动词并在那里返回标头。

您正在发送一个Authorization标头,该标头不在“简单”请求的允许标头列表中,因此完成了预检请求

此外,为了让凭据通过,您必须确保Access-Control-Allow-Credentials: true还设置了标头。

从代码片段中看不出您的请求正文是什么内容类型,但如果它不是application/x-www-form-urlencoded,multipart/form-datatext/plain(例如application/json),您还需要Content-Type使用Access-Control-Allow-Headers: Content-Type.

于 2020-04-14T11:13:38.850 回答