放大:即使在 API 网关和 Lambda 标头中启用了 CORS,但 CORS 标头“Access-Control-Allow-Origin”缺失错误
Posted
技术标签:
【中文标题】放大:即使在 API 网关和 Lambda 标头中启用了 CORS,但 CORS 标头“Access-Control-Allow-Origin”缺失错误【英文标题】:Amplify: CORS header ‘Access-Control-Allow-Origin’ missing error even though CORS is enabled in API Gateway and Lambda headers 【发布时间】:2020-07-27 02:22:13 【问题描述】:我正在使用 Amplify,并让我的 API 网关代理到 Lambda。我在 /proxy+
上启用了 CORS 并部署了 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 应用程序使用不记名令牌时,它会像上面一样失败。
【问题讨论】:
总是引用 full 错误消息。我怀疑它说预检响应中缺少标头,而不是请求的资源。 GET 请求中缺少标头。 OPTIONS 请求运行良好。 更新了问题以包含更多详细信息。 你找到解决方案了吗? 【参考方案1】:我假设您忘记处理用于 preflight request 的 OPTIONS
动词并在那里返回标题。
您正在发送一个Authorization
标头,它不在"simple" requests 的允许标头列表中,因此preflighted request 已完成。
此外,为了credentials to get through,您必须确保也设置了Access-Control-Allow-Credentials: true
标头。
从代码 sn-p 中看不出您的请求正文是什么内容类型,但如果不是application/x-www-form-urlencoded
、multipart/form-data
或text/plain
(比如application/json
),您还需要将其列入白名单Content-Type
标头使用Access-Control-Allow-Headers: Content-Type
。
【讨论】:
OPTIONS
正在处理(某处),因为它返回 access-control-allow-origin: *
。我更新了我的函数以在响应标头中包含"Access-Control-Allow-Credentials": True
。同样的情况。 Access-Control-Allow-Headers
在 API Gateway 中默认设置为 'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'
。
如果你把 Fiddler 放在中间会发生什么?检查实际超出范围的内容以及它与您的测试有何不同。也许您在服务器中遇到错误(例如身份验证无效),然后不会返回这些标头(因为您似乎只在状态为 200 的成功案例中返回它们)?也许您的授权标头没有发送,因为您的库没有将withCredentials: true
传递给 XHR...【参考方案2】:
我遇到了同样的问题。我的飞行前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
等方法)
【讨论】:
【参考方案3】:当我从我的 API Gateway OPTIONS 端点中删除 Cognito 身份验证时,在 js 中使用 fetch()
时,它起作用了。 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."
【讨论】:
【参考方案4】:我刚刚遇到过类似的事情。这里的问题询问为什么浏览器在使用 Amplify 访问 API 网关时返回 CORS 错误,尽管在端点中正确配置了 CORS 标头。
除了不正确的 CORS 标头配置之外,如果请求的某些方面不正确,Amplify/API Gateway 会给出 CORS 错误。我遇到的有:
您使用的 HTTP 谓词不存在于端点上 您使用的端点不存在(例如拼写错误) Content-Type 标头不正确后者给我带来了问题。似乎Amplify.API.post
和Amplify.API.put
默认都发送application/x-www-form-urlencoded
的Content-Type。我的 API 期待 application/json
,结果是 CORS 错误。
【讨论】:
【参考方案5】:在我使用 Amplify 并尝试保护 API 网关,使其只有通过 Cognito 登录的用户才能访问时,我遇到了同样的问题。
您可能也错过了我错过的步骤是 AWS API-Gateway 中的一些配置。您需要转到网关仪表板并创建一个使用您的 Cognito 用户池的“授权者”。 token source
将是您为此使用的任何标题标签(通常是“授权”)。
但你还没有完成。然后,您需要转到“资源”并更改方法请求以使用您刚刚创建的新授权方。
希望在做完这一切之后,你应该会没事的。如果您的用户已登录,并且您按原样添加 Authorization 标头:
let myInit =
headers:
Authorization: `Bearer $(await Auth.currentSession())
.getIdToken()
.getJwtToken()`
;
希望一切顺利。
可以在here on Youtube, and starting around 10:50上找到显示这些步骤的视频指南
【讨论】:
以上是关于放大:即使在 API 网关和 Lambda 标头中启用了 CORS,但 CORS 标头“Access-Control-Allow-Origin”缺失错误的主要内容,如果未能解决你的问题,请参考以下文章
如何避免通过重新映射无服务器框架从 Lambda 传递回 API 网关的标头?
React.js - CORS 策略:请求的资源上不存在“Access-Control-Allow-Origin”标头。 [AWS - Lambda - API 网关]
CORS - Api 网关、lambda 和 vue.js [关闭]
使用 Rest API Gateway lambda 集成 CORS 问题进行放大