Chrome忽略了Access-Control-Allow-Origin标头,并在调用AWS Lambda时因预检错误而使CORS失败 [英] Chrome is ignoring Access-Control-Allow-Origin header and fails CORS with preflight error when calling AWS Lambda

查看:119
本文介绍了Chrome忽略了Access-Control-Allow-Origin标头,并在调用AWS Lambda时因预检错误而使CORS失败的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在构建一个ReactJS前端,该前端必须使用JS提取从AWS Lambdas收集一些数据.我无法使其正常运行,无论我采用哪种CORS技术都无济于事.我在这里没有找到其他答案.

I'm building a ReactJS frontend that has to gather some data from AWS Lambdas using a JS fetch. I cannot make it work, no mater what CORS technique I apply. I've looked into other answers here to no avail.

我肯定在响应中添加了带有"*" 值的 Access-Control-Allow-Origin (已使用邮递员调用端点进行了验证).此外,Chrome抱怨使用对预检请求的响应未通过访问控制检查进行预检,但是chrome实际上从未触发过预检请求( OPTIONS 方法),所有我看到的是我首先尝试制作的 GET ,这确实令人困惑.

I am definitely adding Access-Control-Allow-Origin with "*" value in my response (verified this using postman to call the endpoint). Also, Chrome complains about the preflight with Response to preflight request doesn't pass access control check, but no preflight request (OPTIONS method) is ever actually fired by chrome, all I see is the GET I'm trying to make on the first place, which is really confusing.

我想念什么?为什么没有提出OPTIONS预检请求,chrome会抱怨预检?为什么在响应中添加带有"*" Access-Control-Allow-Origin 还不够?

What am I missing? Why is chrome complaining about preflight when no OPTIONS preflight request is made? Why adding Access-Control-Allow-Origin with "*" in my response is not enough?

谢谢!

推荐答案

TL; DR:发生了 的预检请求,只是没有在chrome上显示(有一种方法可以使它们显示出来).另外,如果您将自定义标头用于授权令牌,则需要进行一些调整.

TL;DR: There was a preflight request happening, it just wasn't showing on chrome (there's a way to make them show up). Also, there's a tweak to make if you use custom headers for authorization tokens for example.

摘要

好吧,在研究了一天并检查了其他几个答案之后,我将其发布,因为没有一个适合我的问题,希望它将对其他面临此问题的人有所帮助.首先,我将总结该错误涉及的几个部分,然后再解决该问题,而无需诉诸任何拙劣的"解决方案,例如绕开带有chrome扩展名的CORS或使用任何第三方服务(如许多帖子所建议的那样).我的设置如下:

Well, after looking into this for a day and checking several other answers I'm posting this because none quite fit my problem, with the hope it will help anyone else facing this. First, I'll summarize the several parts involved in the error and then how to fix it, without resorting to any "hackish" solution like bypassing CORS with a chrome extension, or using any 3rd party service, like many posts suggest. My setup looked like this:

  • ReactJS前端,尝试使用获取JavaScript方法进行GET请求,并在 http://localhost:3000 上运行为发展
  • AWS Lambda后端,它使用JSON负载(用python编码,并不重要,但无论如何)来回答GET.此lambda在其响应中添加 Access-Control-Allow-Origin:"*" 标头.
  • 上述AWS Lambda位于AWS称为授权者"的后面,该功能在您的lambda之前运行,以检查您想要用来保护对API的访问的任何授权标头.这一点很重要,我们将在后面看到,因为由于AWS内部工作方式的某些废话,有时您无法使用标准的HTTP Authorization标头,并且默认情况下使用他们在其文档和示例中建议的authorizationToken(并且并不总是对其进行更改)的方法,有很多用户在其论坛中对此进行了举报).稍后我们将对此进行记录.
  • 使用AWS API Gateway在互联网上路由和发布这两种API方法(实际API及其授权者),简而言之,这是将您的lambda与公共URL配对以从其他地方调用它的一种方式.
  • 用作浏览器的Google Chrome(已启用其开发人员工具来监视事物)

错误

当尝试调用lambda时,Chrome会阻止GET请求,并在控制台上显示此错误:对预检请求的响应未通过访问控制检查.我的lambda已经用正确的 Access-Control-Allow-Origin 标头回答了,那怎么了?另外,无论如何都没有发出飞行前 OPTIONS 请求,所以这很令人困惑.

When trying to call the lambda, chrome blocks the GET request with this error showing on the console: Response to preflight request doesn't pass access control check. My lambda is already answering with the correct Access-Control-Allow-Origin header so, what's wrong? Also, no preflight OPTIONS request are being made anyways, so this was confusing.

一些调试

AWS Lambda很棒,但是它们的调试工具没有我想要的那么流畅,因此我用本地的expressjs服务器替换了lambda,仅实现了两种方法:GET/foo和OPTIONS/foo.令我惊讶的是,当我从ReactJS前端获取/foo时,它先 did 调用了OPTIONS/foo(我通过将日志添加到端点来确认了这一点,等等,您也可以在lambdas中进行此操作,但它不太容易).

AWS Lambda is great but their debugging tools are not as fluid as I would like, so I replaced the lambda with a local expressjs server, implementing just two methods: GET /foo and OPTIONS /foo. To my surprise, when from my ReactJS frontend I fetched /foo, it did call OPTIONS /foo first (I confirmed this by adding logs to my endpoint, etc, something you can also do in lambdas but its not as easy).

实际发生的事情

预检"请求是一个OPTIONS请求,用于验证执行以下GET时实际允许的操作,但是Chrome中的网络"标签未显示任何实际发生的OPTIONS请求(我记得它们曾经出现在这里).好吧,他们在某个时候更改了它,现在默认情况下它们是隐藏的.如果您希望它们再次显示(作为开发人员,我愿意),可以通过将 -of-blink-cors 标志更改为 disabled 来重新启用它此处.

A "preflight" request is an OPTIONS request to validate what is actually allowed when doing the following GET, but the Network tab in Chrome was not showing any OPTIONS request actually happening (I remember they used to show up here). Well, they changed it at some point, and now they are hidden by default. If you want them to show again (as a developer, I do), you can re-enable that by changing the out-of-blink-cors flag to disabled as explained here.

更改此标志后,现在显示在网络"标签上.从那里,我可以制作OPTIONS响应,以便以后可以启用所需的GET.使用凭据和其他情况时,还有其他注意事项(我发现 Mozilla的这篇文章对此有帮助),但简而言之,我的OPTIONS响应标头看起来像这样:

After changing this flag, now the OPTIONS request does show on the network tab. From there I could craft the OPTIONS response so it would enable the required GET afterwards. There are other considerations when using credentials and other cases (I found this article from Mozilla helpful with that), but in short my OPTIONS response headers look like this:

Access-Control-Allow-Origin: "http://localhost:3000"
Access-Control-Allow-Methods: "GET, POST, OPTIONS"
Access-Control-Allow-Headers: "authorizationToken"

(最后一个 Access-Control-Allow-Headers 在处理AWS Lambdas Authorizer时起作用.如果您使用该自定义标头发送令牌,则需要允许它在这里).

(That last one, Access-Control-Allow-Headers, comes into play when dealing with AWS Lambdas Authorizers. If you are using that custom header to send your tokens, you need to allow it here).

在使CORS在本地工作之后,为了解决我的lambda,我做了两件事:

After making CORS work locally, to solve it for my lambdas I did two things:

  1. 您需要API网关才能回答OPTIONS请求.有多种方法可以实现此目的,从编写自己的lambda来回答它,到让AWS为您模拟响应.此处.
  2. 您需要确保GET lambda添加 Access-Control-Allow-Origin 标头,并指向与OPTIONS响应相同的值(在我的情况下,
  1. You need your API Gateway to be able to answer OPTIONS request. There are a number of ways to achieve this, from writing your own lambda to answer it to having AWS to mock-response it for you. More info on that here.
  2. You need to make sure your GET lambda adds the Access-Control-Allow-Origin header, pointing to the same value your OPTIONS response did (In my case, http://localhost:3000).

在那之后,一切都按预期进行.

After that, all worked as expected.

最终提示

我之所以写这个答案,是因为我发现周围的任何问题实际上都没有涵盖"React-CORS-AWS-Authorization"的连词.

I wrote this answer because I found the conjunction of "React-CORS-AWS-Authorization" was not actually covered by any questions I found around.

使用本地主机在chrome上进行开发也可能会引起许多问题,从而导致建议使用诸如lvh.me之类的外部服务,但事实并非如此,有些答案误导了将此CORS问题与那.此外,一些答案表明,要禁用CORS检查,同时禁用某些chrome扩展程序,这确实是一个糟糕的安全建议.

Also there are a number of problems that may arise from using localhost for development on chrome, leading to suggestions of using an external service like lvh.me, but this was not the case, and some answers misleadingly relate this CORS problem to that. Moreover, some answers suggest disabling CORS checks altogether with some chrome extension, which is really bad security advice.

最后,我发现制作一个简单的expressJS服务器来调试服务器端的想法对于理解正在发生的事情非常有帮助,因为有时您根本无法访问另一端正在发生的事情,所以也许这个建议可能会有所帮助人们缩短了处理此类事情的时间.

Finally, I found the idea of making a simple expressJS server to debug the server-side of things pretty helpful in understanding what was happening, because sometimes you simply cannot access what's happening on the other side, so maybe this suggestion might help people shorten the time dealing with things like this.

这篇关于Chrome忽略了Access-Control-Allow-Origin标头,并在调用AWS Lambda时因预检错误而使CORS失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆