AWS API 网关 CORS
AWS API Gateway CORS
我正在使用 Terraform 部署我的 AWS 基础设施。部署 REST API 资源时,出现错误(如图所示)。
我启用了 CORS,但它一直告诉我 CORS 有问题。但是,当我在 AWS 控制台中使用相同的参数创建相同的资源时,我没有任何错误并且一切顺利。就在通过 Terraform 创建它时,我遇到了这种错误。
这是我的 Terraform 代码:
resource "aws_api_gateway_rest_api" "api" {
name = "api"
binary_media_types = [
"image/jpeg",
]
}
# ----------------------------------------------------------------------
# CREATE API RESOURCE
# ----------------------------------------------------------------------
resource "aws_api_gateway_resource" "resource" {
rest_api_id = aws_api_gateway_rest_api.api.id
parent_id = aws_api_gateway_rest_api.api.root_resource_id
path_part = "upload"
}
# ----------------------------------------------------------------------
# CREATE API RESOURCE METHOD
# ----------------------------------------------------------------------
resource "aws_api_gateway_method" "method" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = "POST"
authorization = "NONE"
}
# ----------------------------------------------------------------------
# ATTACH LAMBDA functions TO METHOD (INTEGRATION)
# ----------------------------------------------------------------------
resource "aws_api_gateway_integration" "integration" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.method.http_method
integration_http_method = "POST"
type = "AWS"
uri = aws_lambda_function.addImageToS3.invoke_arn
passthrough_behavior = "WHEN_NO_MATCH"
request_templates = {
"image/jpeg" = "${file("mapping_template.template")}"
}
}
# ----------------------------------------------------------------------
# ADD PERMISSION TO API SO THAT IT CAN INVOKE THE FUNCTION
# ----------------------------------------------------------------------
resource "aws_lambda_permission" "api-permission" {
statement_id = "AllowExecutionFromApiGateway"
action = "lambda:InvokeFunction"
function_name = "${aws_lambda_function.addImageToS3.function_name}"
principal = "apigateway.amazonaws.com"
}
# ----------------------------------------------------------------------
# DEPLOY API
# ----------------------------------------------------------------------
resource "aws_api_gateway_deployment" "deployment" {
depends_on = [
aws_api_gateway_integration.integration
]
rest_api_id = aws_api_gateway_rest_api.api.id
stage_name = "fnp"
}
# ----------------------------------------------------------------------
# BODY OF LAMBDA
# ----------------------------------------------------------------------
data "archive_file" "addImageToS3" {
type = "zip"
source_file = "./functions/addImageToS3.py"
output_path = "./functions/addImageToS3.zip"
}
# ----------------------------------------------------------------------
# CREATE FUNCTION TO DESCRIBE PROCESSOR: RUNNING,STARTING OR STOPPED
# ----------------------------------------------------------------------
resource "aws_lambda_function" "addImageToS3" {
filename = "./functions/addImageToS3.zip"
function_name = "addImageToS3"
role = aws_iam_role.api_assumRoleLambda.arn
handler = "addImageToS3.lambda_handler"
runtime = "python3.8"
environment {
variables = {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
}
}
}
# ----------------------------------------------------------------------
# Lambda Execution Role
# ----------------------------------------------------------------------
resource "aws_iam_role" "api_assumRoleLambda" {
name = "api_assumRoleLambda"
assume_role_policy = file("./policies/assumRoleLambda.json")
}
# ----------------------------------------------------------------------
# POLICY TO DECRYPTE ENVIRONMENT VARIABLES
# ----------------------------------------------------------------------
resource "aws_iam_role_policy" "kms_policy" {
name = "kmsDecrypte"
role = aws_iam_role.api_assumRoleLambda.id
policy = file("./policies/kms_policy.json")
depends_on = [
aws_iam_role.api_assumRoleLambda,
]
}
output "url" {
value = aws_api_gateway_deployment.deployment.invoke_url
}
resource "aws_api_gateway_method_response" "cors-post" {
depends_on = [aws_api_gateway_method.method]
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.method.http_method
status_code = 200
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = true,
"method.response.header.Access-Control-Allow-Methods" = true,
"method.response.header.Access-Control-Allow-Headers" = true
}
response_models = {
"application/json" = "Empty"
}
}
resource "aws_api_gateway_integration_response" "cors-post" {
depends_on = [aws_api_gateway_integration.cors, aws_api_gateway_method_response.cors-post]
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.method.http_method
status_code = 200
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = "'*'", # replace with hostname of frontend (CloudFront)
"method.response.header.Access-Control-Allow-Headers" = "'Content-Type'",
"method.response.header.Access-Control-Allow-Methods" = "'GET, POST'" # remove or add HTTP methods as needed
}
}
# ----------------------------------------------------------------------
# CORS
# ----------------------------------------------------------------------
resource "aws_api_gateway_method" "cors" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = "OPTIONS"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "cors" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.cors.http_method
type = "MOCK"
}
resource "aws_api_gateway_method_response" "cors" {
depends_on = [aws_api_gateway_method.cors]
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.cors.http_method
status_code = 200
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = true,
"method.response.header.Access-Control-Allow-Methods" = true,
"method.response.header.Access-Control-Allow-Headers" = true
}
response_models = {
"application/json" = "Empty"
}
}
resource "aws_api_gateway_integration_response" "cors" {
depends_on = [aws_api_gateway_integration.cors, aws_api_gateway_method_response.cors]
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.cors.http_method
status_code = 200
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = "'*'",
"method.response.header.Access-Control-Allow-Headers" = "'Content-Type'",
"method.response.header.Access-Control-Allow-Methods" = "'GET, POST'" # remove or add HTTP methods as needed
}
}
resource "aws_api_gateway_gateway_response" "response_4xx" {
rest_api_id = aws_api_gateway_rest_api.api.id
response_type = "DEFAULT_4XX"
response_templates = {
"application/json" = "{'message':$context.error.messageString}"
}
response_parameters = {
"gatewayresponse.header.Access-Control-Allow-Origin" = "'*'" # replace with hostname of frontend (CloudFront)
}
}
resource "aws_api_gateway_gateway_response" "response_5xx" {
rest_api_id = aws_api_gateway_rest_api.api.id
response_type = "DEFAULT_5XX"
response_templates = {
"application/json" = "{'message':$context.error.messageString}"
}
response_parameters = {
"gatewayresponse.header.Access-Control-Allow-Origin" = "'*'"
}
}
在映射模板中:
{
"content":"$input.body",
"key":"$input.params('name')"
}
感谢您的回复
检查生成的 json 并注意到在使用 Terraform 部署后未添加一些 http 方法
我正在使用 Terraform 部署我的 AWS 基础设施。部署 REST API 资源时,出现错误(如图所示)。
resource "aws_api_gateway_rest_api" "api" {
name = "api"
binary_media_types = [
"image/jpeg",
]
}
# ----------------------------------------------------------------------
# CREATE API RESOURCE
# ----------------------------------------------------------------------
resource "aws_api_gateway_resource" "resource" {
rest_api_id = aws_api_gateway_rest_api.api.id
parent_id = aws_api_gateway_rest_api.api.root_resource_id
path_part = "upload"
}
# ----------------------------------------------------------------------
# CREATE API RESOURCE METHOD
# ----------------------------------------------------------------------
resource "aws_api_gateway_method" "method" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = "POST"
authorization = "NONE"
}
# ----------------------------------------------------------------------
# ATTACH LAMBDA functions TO METHOD (INTEGRATION)
# ----------------------------------------------------------------------
resource "aws_api_gateway_integration" "integration" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.method.http_method
integration_http_method = "POST"
type = "AWS"
uri = aws_lambda_function.addImageToS3.invoke_arn
passthrough_behavior = "WHEN_NO_MATCH"
request_templates = {
"image/jpeg" = "${file("mapping_template.template")}"
}
}
# ----------------------------------------------------------------------
# ADD PERMISSION TO API SO THAT IT CAN INVOKE THE FUNCTION
# ----------------------------------------------------------------------
resource "aws_lambda_permission" "api-permission" {
statement_id = "AllowExecutionFromApiGateway"
action = "lambda:InvokeFunction"
function_name = "${aws_lambda_function.addImageToS3.function_name}"
principal = "apigateway.amazonaws.com"
}
# ----------------------------------------------------------------------
# DEPLOY API
# ----------------------------------------------------------------------
resource "aws_api_gateway_deployment" "deployment" {
depends_on = [
aws_api_gateway_integration.integration
]
rest_api_id = aws_api_gateway_rest_api.api.id
stage_name = "fnp"
}
# ----------------------------------------------------------------------
# BODY OF LAMBDA
# ----------------------------------------------------------------------
data "archive_file" "addImageToS3" {
type = "zip"
source_file = "./functions/addImageToS3.py"
output_path = "./functions/addImageToS3.zip"
}
# ----------------------------------------------------------------------
# CREATE FUNCTION TO DESCRIBE PROCESSOR: RUNNING,STARTING OR STOPPED
# ----------------------------------------------------------------------
resource "aws_lambda_function" "addImageToS3" {
filename = "./functions/addImageToS3.zip"
function_name = "addImageToS3"
role = aws_iam_role.api_assumRoleLambda.arn
handler = "addImageToS3.lambda_handler"
runtime = "python3.8"
environment {
variables = {
region = var.region
access_key = var.access_key
secret_key = var.secret_key
}
}
}
# ----------------------------------------------------------------------
# Lambda Execution Role
# ----------------------------------------------------------------------
resource "aws_iam_role" "api_assumRoleLambda" {
name = "api_assumRoleLambda"
assume_role_policy = file("./policies/assumRoleLambda.json")
}
# ----------------------------------------------------------------------
# POLICY TO DECRYPTE ENVIRONMENT VARIABLES
# ----------------------------------------------------------------------
resource "aws_iam_role_policy" "kms_policy" {
name = "kmsDecrypte"
role = aws_iam_role.api_assumRoleLambda.id
policy = file("./policies/kms_policy.json")
depends_on = [
aws_iam_role.api_assumRoleLambda,
]
}
output "url" {
value = aws_api_gateway_deployment.deployment.invoke_url
}
resource "aws_api_gateway_method_response" "cors-post" {
depends_on = [aws_api_gateway_method.method]
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.method.http_method
status_code = 200
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = true,
"method.response.header.Access-Control-Allow-Methods" = true,
"method.response.header.Access-Control-Allow-Headers" = true
}
response_models = {
"application/json" = "Empty"
}
}
resource "aws_api_gateway_integration_response" "cors-post" {
depends_on = [aws_api_gateway_integration.cors, aws_api_gateway_method_response.cors-post]
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.method.http_method
status_code = 200
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = "'*'", # replace with hostname of frontend (CloudFront)
"method.response.header.Access-Control-Allow-Headers" = "'Content-Type'",
"method.response.header.Access-Control-Allow-Methods" = "'GET, POST'" # remove or add HTTP methods as needed
}
}
# ----------------------------------------------------------------------
# CORS
# ----------------------------------------------------------------------
resource "aws_api_gateway_method" "cors" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = "OPTIONS"
authorization = "NONE"
}
resource "aws_api_gateway_integration" "cors" {
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.cors.http_method
type = "MOCK"
}
resource "aws_api_gateway_method_response" "cors" {
depends_on = [aws_api_gateway_method.cors]
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.cors.http_method
status_code = 200
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = true,
"method.response.header.Access-Control-Allow-Methods" = true,
"method.response.header.Access-Control-Allow-Headers" = true
}
response_models = {
"application/json" = "Empty"
}
}
resource "aws_api_gateway_integration_response" "cors" {
depends_on = [aws_api_gateway_integration.cors, aws_api_gateway_method_response.cors]
rest_api_id = aws_api_gateway_rest_api.api.id
resource_id = aws_api_gateway_resource.resource.id
http_method = aws_api_gateway_method.cors.http_method
status_code = 200
response_parameters = {
"method.response.header.Access-Control-Allow-Origin" = "'*'",
"method.response.header.Access-Control-Allow-Headers" = "'Content-Type'",
"method.response.header.Access-Control-Allow-Methods" = "'GET, POST'" # remove or add HTTP methods as needed
}
}
resource "aws_api_gateway_gateway_response" "response_4xx" {
rest_api_id = aws_api_gateway_rest_api.api.id
response_type = "DEFAULT_4XX"
response_templates = {
"application/json" = "{'message':$context.error.messageString}"
}
response_parameters = {
"gatewayresponse.header.Access-Control-Allow-Origin" = "'*'" # replace with hostname of frontend (CloudFront)
}
}
resource "aws_api_gateway_gateway_response" "response_5xx" {
rest_api_id = aws_api_gateway_rest_api.api.id
response_type = "DEFAULT_5XX"
response_templates = {
"application/json" = "{'message':$context.error.messageString}"
}
response_parameters = {
"gatewayresponse.header.Access-Control-Allow-Origin" = "'*'"
}
}
在映射模板中:
{
"content":"$input.body",
"key":"$input.params('name')"
}
感谢您的回复
检查生成的 json 并注意到在使用 Terraform 部署后未添加一些 http 方法