如何解决没有“Access-Control-Allow-Origin”的问题使用 terraform cloudfront 和 django 创建新端点时

发布于 2025-01-11 19:27:38 字数 6021 浏览 0 评论 0原文

我使用 django React、terrafor、aws cloudfront 和 nginx 创建了一个应用程序,

我已经工作了数周的所有端点都运行良好。

现在,当我尝试从前端发出请求时,我尝试添加新端点,出现以下错误:

Access to XMLHttpRequest at 'https: //api.foo.com/new-url-enpoints/' from origin 'https: //www.foo.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
main.a1abe898.chunk.js:1 Page error:  Error: Network Error
    at e.exports (1.v3s1s213.chunk.js:1:21345)
    at XMLHttpRequest.p.onerror (1.v3s1s213.chunk.js:1:63362)
1.v3s1s213.chunk.js:1          POST https: //api.foo.com/new-url-enpoints/ net::ERR_FAILED 500

S3 Bucket


resource "aws_s3_bucket" "my_bucket" {
  bucket        = "some-bucket"
  ...

  cors_rule {
    allowed_headers = [
      "Accept",
      "Accept-Encoding",
      "Authorization",
      "Content-Type",
      "Dnt",
      "Origin",
      "User-Agent",
      "X-Csrftoken",
      "X-Requested-With",
    ]
    allowed_methods = ["PUT", "POST", "GET", "DELETE", "HEAD"]
    allowed_origins = ["https: //www.foo.com"] # i have created the space to be able to post this question on stackoverflow
    expose_headers  = ["Etag"]
    max_age_seconds = 3000
  }

FRONTEND

locals {
  s3_origin_id = "www.foo.com"
}

resource "aws_cloudfront_distribution" "front_end_cloudfront" {
  origin {
    domain_name = aws_s3_bucket.my_bucket.bucket_regional_domain_name
    origin_id   = local.s3_origin_id

    s3_origin_config {
      origin_access_identity = "${aws_cloudfront_origin_access_identity.s3_oai.cloudfront_access_identity_path}"
    }
  }

  enabled             = true
  is_ipv6_enabled     = true
  default_root_object = "index.html"

  aliases = ["www.foo.com"]

  custom_error_response {
    error_caching_min_ttl = 500
    error_code            = 403
    response_code         = 403
    response_page_path    = "/index.html"
  }

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "DELETE"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = local.s3_origin_id

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
  }

  # cache behavior with precedence 0
  ordered_cache_behavior {
    path_pattern     = "/content/immutable/*"
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "DELETE"]
    cached_methods   = ["GET", "HEAD", "OPTIONS"]
    target_origin_id = local.s3_origin_id

    forwarded_values {
      query_string = false
      headers      = ["Origin"]

      cookies {
        forward = "none"
      }
    }

    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
    compress               = true
    viewer_protocol_policy = "redirect-to-https"
  }

  # cache behavior with precedence 1
  ordered_cache_behavior {
    path_pattern     = "/content/*"
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "DELETE"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = local.s3_origin_id

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }

    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
    compress               = true
    viewer_protocol_policy = "redirect-to-https"
  }

  ...
}

BACKEND

locals {
  lb_origin_id = "api.foo.com"
}

resource "aws_cloudfront_distribution" "backend_cloudfront" {
  origin {
    domain_name = aws_lb.backend_lb.dns_name
    origin_id   = local.lb_origin_id

    custom_origin_config {
      http_port  = 80
      https_port = 443
      origin_protocol_policy = "http-only"
      origin_ssl_protocols = ["TLSv1.2"]
    }
  }

  enabled             = true
  is_ipv6_enabled     = true

  aliases = ["api.foo.com"]

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "DELETE"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = local.lb_origin_id

    forwarded_values {
      query_string            = true
      headers                 = ["*"]
      query_string_cache_keys = []

      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
  }

  # cache behavior with precedence 0
  ordered_cache_behavior {
    path_pattern     = "/api/*"
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "DELETE"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = local.lb_origin_id

    forwarded_values {
      query_string            = true
      headers                 = ["*"]
      query_string_cache_keys = []

      cookies {
        forward = "none"
      }
    }

    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
    compress               = true
    viewer_protocol_policy = "redirect-to-https"
  }

  ...
}

nginx

server {

        listen 80;
        server_name SECRET;

        location / {
                add_header 'Access-Control-Allow-Origin' 'h ttps://www.foo.com' always; # space created on purpose
                add_header 'Access-Control-Allow-Credentials' 'true' always;
                add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH,HEAD' always;
                add_header 'X-XSS-Protection' '1; mode=block' always;
                add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,X-Mx-ReqToken,X-Requested-With,Keep-Alive,X-CsrfToken' always;
                ...
        }
        ....
}


此配置一直失败,仅适用于创建的新端点,我认为它应该与带有cloudfront的缓存,但我不确定如何修复

任何帮助将不胜感激

I have created an application using django react, terrafor, aws cloudfront and nginx

all my endpoints that i have been working on for weeks work well.

Now i have tried to add new endpoints when i try to make a request from the front end, i get the following errors:

Access to XMLHttpRequest at 'https: //api.foo.com/new-url-enpoints/' from origin 'https: //www.foo.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
main.a1abe898.chunk.js:1 Page error:  Error: Network Error
    at e.exports (1.v3s1s213.chunk.js:1:21345)
    at XMLHttpRequest.p.onerror (1.v3s1s213.chunk.js:1:63362)
1.v3s1s213.chunk.js:1          POST https: //api.foo.com/new-url-enpoints/ net::ERR_FAILED 500

S3 bucket


resource "aws_s3_bucket" "my_bucket" {
  bucket        = "some-bucket"
  ...

  cors_rule {
    allowed_headers = [
      "Accept",
      "Accept-Encoding",
      "Authorization",
      "Content-Type",
      "Dnt",
      "Origin",
      "User-Agent",
      "X-Csrftoken",
      "X-Requested-With",
    ]
    allowed_methods = ["PUT", "POST", "GET", "DELETE", "HEAD"]
    allowed_origins = ["https: //www.foo.com"] # i have created the space to be able to post this question on stackoverflow
    expose_headers  = ["Etag"]
    max_age_seconds = 3000
  }

FRONTEND

locals {
  s3_origin_id = "www.foo.com"
}

resource "aws_cloudfront_distribution" "front_end_cloudfront" {
  origin {
    domain_name = aws_s3_bucket.my_bucket.bucket_regional_domain_name
    origin_id   = local.s3_origin_id

    s3_origin_config {
      origin_access_identity = "${aws_cloudfront_origin_access_identity.s3_oai.cloudfront_access_identity_path}"
    }
  }

  enabled             = true
  is_ipv6_enabled     = true
  default_root_object = "index.html"

  aliases = ["www.foo.com"]

  custom_error_response {
    error_caching_min_ttl = 500
    error_code            = 403
    response_code         = 403
    response_page_path    = "/index.html"
  }

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "DELETE"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = local.s3_origin_id

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
  }

  # cache behavior with precedence 0
  ordered_cache_behavior {
    path_pattern     = "/content/immutable/*"
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "DELETE"]
    cached_methods   = ["GET", "HEAD", "OPTIONS"]
    target_origin_id = local.s3_origin_id

    forwarded_values {
      query_string = false
      headers      = ["Origin"]

      cookies {
        forward = "none"
      }
    }

    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
    compress               = true
    viewer_protocol_policy = "redirect-to-https"
  }

  # cache behavior with precedence 1
  ordered_cache_behavior {
    path_pattern     = "/content/*"
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "DELETE"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = local.s3_origin_id

    forwarded_values {
      query_string = false

      cookies {
        forward = "none"
      }
    }

    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
    compress               = true
    viewer_protocol_policy = "redirect-to-https"
  }

  ...
}

BACKEND

locals {
  lb_origin_id = "api.foo.com"
}

resource "aws_cloudfront_distribution" "backend_cloudfront" {
  origin {
    domain_name = aws_lb.backend_lb.dns_name
    origin_id   = local.lb_origin_id

    custom_origin_config {
      http_port  = 80
      https_port = 443
      origin_protocol_policy = "http-only"
      origin_ssl_protocols = ["TLSv1.2"]
    }
  }

  enabled             = true
  is_ipv6_enabled     = true

  aliases = ["api.foo.com"]

  default_cache_behavior {
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "DELETE"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = local.lb_origin_id

    forwarded_values {
      query_string            = true
      headers                 = ["*"]
      query_string_cache_keys = []

      cookies {
        forward = "none"
      }
    }

    viewer_protocol_policy = "redirect-to-https"
    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
  }

  # cache behavior with precedence 0
  ordered_cache_behavior {
    path_pattern     = "/api/*"
    allowed_methods  = ["GET", "HEAD", "OPTIONS", "PATCH", "POST", "PUT", "DELETE"]
    cached_methods   = ["GET", "HEAD"]
    target_origin_id = local.lb_origin_id

    forwarded_values {
      query_string            = true
      headers                 = ["*"]
      query_string_cache_keys = []

      cookies {
        forward = "none"
      }
    }

    min_ttl                = 0
    default_ttl            = 0
    max_ttl                = 0
    compress               = true
    viewer_protocol_policy = "redirect-to-https"
  }

  ...
}

nginx

server {

        listen 80;
        server_name SECRET;

        location / {
                add_header 'Access-Control-Allow-Origin' 'h ttps://www.foo.com' always; # space created on purpose
                add_header 'Access-Control-Allow-Credentials' 'true' always;
                add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH,HEAD' always;
                add_header 'X-XSS-Protection' '1; mode=block' always;
                add_header 'Access-Control-Allow-Headers' 'Authorization,Content-Type,Accept,Origin,User-Agent,DNT,X-Mx-ReqToken,X-Requested-With,Keep-Alive,X-CsrfToken' always;
                ...
        }
        ....
}


this configuration keep failing , only for the new endpoints created, i think it should be related to the cache with cloudfront but i am not sure how to fix

any help would be much appreciated

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

一杆小烟枪 2025-01-18 19:27:38

如果错误确实是由于 cloudfront 配置引起的,我认为下面应该可以解决您的问题。 CloudFront 分配配置应转发源所需的标头。如果您的源是 S3 存储桶,则配置您的分配以将以下标头转发到 Amazon S3:

  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Origin

执行此更改的步骤:

  1. 从 CloudFront 控制台打开您的分配。
  2. 选择行为选项卡。
  3. 选择创建行为。或者,选择现有行为,然后选择编辑。
  4. 在缓存密钥和源请求下,选择缓存策略和源请求策略。然后,对于源请求策略,从下拉列表中选择 CORS-S3Origin 或 CORS-CustomOrigin。
  5. 选择保存更改。

来源:https://aws.amazon .com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/

I think below should solve your issue, if the error is indeed due to cloudfront config. The CloudFront distribution config should forward the headers that are required by your origin. If your origin is an S3 bucket, then configure your distribution to forward the following headers to Amazon S3:

  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Origin

Steps to do this change:

  1. Open your distribution from the CloudFront console.
  2. Choose the Behaviors tab.
  3. Choose Create Behavior. Or, select an existing behavior, and then choose Edit.
  4. Under Cache key and origin requests, choose Cache policy and origin request policy. Then, for Origin request policy, choose either CORS-S3Origin or CORS-CustomOrigin from the dropdown list.
  5. Choose Save Changes.

Src: https://aws.amazon.com/premiumsupport/knowledge-center/no-access-control-allow-origin-error/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文