对 API 网关的 CORS 请求在浏览器中不起作用
Posted
技术标签:
【中文标题】对 API 网关的 CORS 请求在浏览器中不起作用【英文标题】:CORS Request to API Gateway not working in browser 【发布时间】:2021-11-01 12:14:47 【问题描述】:好吧,我已经准备好看起来很傻了。我敢打赌这是一个简单的问题,我只是没有看到我做错了什么。
我最近部署了一个设置 API 网关的 SAM 应用程序。相关配置如下
# SAM Template Headers + Some Parameters; nothing relating to this.
Resources:
# The Api Gateway necessary for the authorizers.
ApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref Stage
Cors: "'*'"
Auth:
DefaultAuthorizer: MyCognitoAuthorizer
Authorizers:
MyCognitoAuthorizer:
UserPoolArn: !ImportValue UserPoolArn
# some other functions, but one function should do it.
# Verified that all functions are referencing the custom ApiGateway resource.
PutTodosFunction:
Type: AWS::Serverless::Function
Properties:
Handler: src/handlers/add.putItemHandler
Description: Adds a todo.
Policies:
- DynamoDBCrudPolicy:
TableName: !Ref TodosTable
Environment:
Variables:
TODOS_TABLE: !Ref TodosTable
NODE_ENV: !If [isProd, 'production', 'development']
REGION: !Ref AWS::Region
Events:
PutTodo:
Type: Api
Properties:
RestApiId: !Ref ApiGateway
Path: /
Method: PUT
这就是我觉得自己快要疯了的地方。如您所见,我的 API Gateway 使用 AWS Cognito 进行授权,因此我使用 Insomnia 桌面应用程序测试流程。
只要我记得提供必要的令牌,所有请求都可以正常工作。在我开始尝试通过浏览器发出相同的请求之前,我认为我是个黄金人。
现在我在尝试发出请求时收到如下错误:
CORS 政策已阻止从源“https://localhost:8080”访问“https://xpquux202j.execute-api.us-west-2.amazonaws.com/alpha/”获取:响应预检请求未通过访问控制检查:请求的资源上不存在“Access-Control-Allow-Origin”标头。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
调用它的代码经历了一些迭代,但最近的是:
const headers = new Headers();
headers.append('Authorization', 'Bearer <JWT Token Goes Here>');
fetch(API_URL,
headers,
method: 'options', // have tried put/get as well. Neither goes through.
mode: 'cors' // tried cors and no-cors
)
.then(console.log)
.catch(console.log);
最初出现错误时,我认为 API 网关端的某些内容配置错误,但向端点发出 OPTIONS
请求(在 Insomnia 中)给出:
并在 中测试它
TYIA 寻求帮助;我确定这是我想念的小东西我有点厌倦了试图弄清楚这一点。
【问题讨论】:
从头开始创建自定义 api 网关 + lambda 并使用我的本地应用程序对其进行测试后,答案是 SAM CLI 生成的 OPTIONS 请求启用了 cognito 授权器。它显然需要不拥有授权人。我现在正在研究如何解决这个问题。否则就像在 aws 帐户中进入控制台,进入 API 网关,找到选项方法,删除授权者并重新部署 API 一样简单 【参考方案1】:好的,原来的问题已经解决了……有点。
Tl;博士,您可以在AWS::Serverless::Api
调用的Auth
键中使用AddDefaultAuthorizerToCorsPreflight
选项,例如
ApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref Stage
Cors: "'*'"
Auth:
DefaultAuthorizer: MyCognitoAuthorizer
AddDefaultAuthorizerToCorsPreflight: false
Authorizers:
MyCognitoAuthorizer:
UserPoolArn: !ImportValue UserPoolArn
然而,这会产生另一个与 CORS 相关的问题。当您使用此设置创建 API 网关时,OPTIONS 请求的响应中没有 Access-Control-Allow-Headers
标头。我仍在等待 AWS Sam 团队关于 Github 问题的回复:https://github.com/aws/serverless-application-model/issues/2136#issuecomment-915708356
到目前为止,解决方法是简单地从控制台启用 CORS,然后它将具有必要的授权标头。显然不是很好,但也不是特别破坏游戏。
更新
经过一番挖掘,我发现进行这些更改可以使 API 网关部署没有错误。 ApiGateway 资源中的 CORS 部分需要如下所示。
ApiGateway:
Type: AWS::Serverless::Api
Properties:
StageName: !Ref Stage
Cors:
AllowHeaders: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token'"
AllowMethods: "'*'"
AllowOrigin: "'*'"
# same Auth: definition as above.
【讨论】:
以上是关于对 API 网关的 CORS 请求在浏览器中不起作用的主要内容,如果未能解决你的问题,请参考以下文章
CORS 在 ASP.NET Web API 2 应用程序中不起作用
对 Kong api 网关端点的基本身份验证请求出现 CORS 错误并且未找到预检