AWS API 网关 CORS [关闭]

Posted

技术标签:

【中文标题】AWS API 网关 CORS [关闭]【英文标题】:AWS API Gateway CORS [closed] 【发布时间】:2021-08-26 12:15:53 【问题描述】:

我正在使用 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')"

感谢您的回复

【问题讨论】:

【参考方案1】:

检查生成的 json,发现使用 Terraform 部署后没有添加一些 http 方法

【讨论】:

以上是关于AWS API 网关 CORS [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

从帖子正文读取时,AWS API 网关 CORS 错误

如何使用 AWS API 网关和 Lambda 通过 CORS?

将表单从客户端发布到 AWS API 网关功能时如何修复 CORS 错误?

Cors - 如何处理需要自定义标头的预检选项请求? (AWS:使用 vpc 端点的私有 API 网关)

修复 AWS API 网关不存在的 CORS“对预检的响应 ...”标头并放大

具有自定义授权者和 CORS 间歇性 200 然后 403 然后 200 的 AWS API 网关 ...奇怪