如何使用 OpenAPI 为 AWS API 网关配置 CORS?



我有一个 OpenAPI 规范,用于通过 CDK 部署的 api。 规范如下所示:

openapi: 3.0.1
info:
title: My API
description: My REST API with CORS enabled
version: 0.1.0
x-amazon-apigateway-cors:
allowOrigins:
- "*"
allowCredentials: true
exposeHeaders:
- "x-apigateway-header"
- "x-amz-date"
- "content-type"
maxAge: 3600
allowMethods:
- "*"
allowHeaders":
- "x-apigateway-header"
- "x-amz-date"
- "content-type"
- "Authorization"
components:
securitySchemes:
lambda:
type: "apiKey"
name: "Authorization"
in: "header"
x-amazon-apigateway-authtype: "custom"
x-amazon-apigateway-authorizer:
authorizerUri: "{{my-lambda-authorizer}}"
authorizerResultTtlInSeconds: 300
type: "token" 
paths:
/user/{id}:
get:
summary: Get info of specified user.
parameters:
- in: path
name: id
required: true
schema:
type: string
responses:
'200':
description: OK
content:
application/json:
schema:
$ref: '#/components/schemas/User'
security:
- lambda: []
x-amazon-apigateway-integration:
uri: "{{my-lambda}}"
passthroughBehavior: "when_no_match"
httpMethod: "POST"
type: "aws_proxy"

当我尝试通过fetch()访问它时,我收到一个错误Failed to load resource: Origin http://localhost:8000 is not allowed by Access-Control-Allow-Origin

fetch('https://api.example.com/user/1')
.then(response => response.json())
.then((user: User) => {
// do something
})
.catch((err) => {
console.log("Error: " + err);
});

该 API 可在api.example.com访问,我正在使用 Gatsby 在localhost:8000本地运行该网站。

AWS 文档似乎指出,当我x-amazon-apigateway-cors规范的根目录时,CORS 已启用,但当我尝试访问 API 时,CORS 似乎没有启用(或工作(。 如何在不需要在控制台中配置的情况下为 API 启用 CORS?

Amazon API Gateway 提供两种类型的 API:REST API 和 HTTP API。REST API是最初随Amazon API Gateway引入的API,而HTTP API于2019年底发布。

根据你的OpenAPI规范的描述,我假设你正在尝试部署一个REST API。然而,x-amazon-apigateway-corsOpenAPI 扩展仅适用于 HTTP API。

您现在有两种选择:要么切换到使用 HTTP API,要么手动配置 CORS。只要您不需要仅由 REST API 支持的功能,我建议您改用 HTTP API,因为这是 Amazon API Gateway 提供的更现代的 API。

如果要使用 REST API,启用 CORS 需要更多的手动配置。AWS 在为 REST API 资源启用 CORS 中对此进行了记录。本质上,您必须确保集成返回正确的 CORS 标头。对于 NodeJS AWS Lambda 函数,可能如下所示:

exports.handler = async (event) => {
const response = {
statusCode: 200,
headers: {
"Access-Control-Allow-Headers" : "Content-Type",
"Access-Control-Allow-Origin": "https://www.example.com",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET"
},
body: JSON.stringify('Hello from Lambda!'),
};
return response;
};

要使 CORS 预飞行请求正常工作,您还必须确保 OPTIONS 请求也返回正确的标头。实现这一点的最简单方法是将 OPTIONS-request 的模拟集成添加到您的 OpenAPI 规范中。那看起来像:

options:
responses:
'200':
description: Default response
headers:
Access-Control-Allow-Headers:
schema:
type: string
Access-Control-Allow-Methods:
schema:
type: string
Access-Control-Allow-Origin:
schema:
type: string
x-amazon-apigateway-integration:
type: mock
requestTemplates:
application/json: |
{"statusCode" : 200}
responses:
default:
statusCode: 200
responseParameters:
method.response.header.Access-Control-Allow-Headers: "'*'"
method.response.header.Access-Control-Allow-Methods: "'OPTIONS,POST'"
method.response.header.Access-Control-Allow-Origin: "'https://example.com/'"

另请注意,现代浏览器不支持 localhost 作为 CORS 的源,因此您可能也需要解决此问题。

最新更新