【问题标题】:Symfony 4.1 - CORS issueSymfony 4.1 - CORS 问题
【发布时间】:2018-11-07 22:09:01
【问题描述】:

我的 symfony 4.1 API 有一些问题:

我正在使用 angular httpclient 通过离子应用程序使用我的 API。

我的问题在于 CORS 标头,尤其是 Access-Control-Allow-Methods

我在使用 CORS 时遇到了问题,因为我的 API 和我的应用程序不在同一个来源上,这使得我安装 nelmio/cors-bundle 来处理 CORS。

我的nelmio_cors.yaml如下:

nelmio_cors:
    paths:
        '^/api/':
            origin_regex: true
            allow_origin: ['*']
            allow_methods: ['GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE']
            allow_headers: ['Content-Type', 'Authorization']
            max_age: 3600

这实际上适用于我从那时起使用的所有方法:

  • 发布请求 [OK]
  • 获取请求 [OK]
  • 删除请求 [OK]

现在我想向我的 API 添加一个 PATCH 路由。我已经用 Postman 测试了控制器,我的工作就像一个魅力。现在,当我从我的角度服务中查询相同的路线时:

        return this.http.patch(this.url + '/api/users/' + userId,
                               dataToPatch, 
                               this.authHeaders)
                        .map(response => response.json());

控制台记录以下内容:

Failed to load http://symfony.local/api/users/1: Method PATCH is not allowed by Access-Control-Allow-Methods in preflight response.

这里可以看到请求的响应头:

Access-Control-Allow-Headers: authorization,content-type
Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE
Access-Control-Allow-Origin: *
Access-Control-Max-Age: 3600
Allow: POST, GET, OPTIONS, PUT, DELETE
Cache-Control: no-cache, private
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Date: Tue, 06 Nov 2018 14:02:51 GMT
Server: nginx
Transfer-Encoding: chunked
X-Powered-By: PHP/7.2.11

如您所见,如果我正确理解 CORS 标头,则不允许使用 PATCH 方法,但为什么在使用 postman 使用 API 时它会起作用。

我还安装了 chrome 的 Allow-Control-Allow-Origin:* 扩展,但也没有成功...

我使用https://github.com/ikamikaz3/docker-symfony 作为我的堆栈,它可以来自那里吗? (可能在某处配置错误?)

如果需要,我可以提供更多代码,但这对我来说似乎是一个愚蠢的错误......

编辑 1:

从 chrome 卸载 Allow-Control-Allow-Origin:* 后,我在登录时得到以下信息

Failed to load http://symfony.local/login_check: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'null' that is not equal to the supplied origin. Origin 'http://localhost:8100' is therefore not allowed access.

编辑 2:

在我的 nginx 容器中使用以下内容更新我的 symfony.conf 后,我设法让 API 工作,PATCH 仍然坏了,但我认为我可以做到

    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
            #
            # Custom headers and headers various browsers *should* be OK with but aren't
            #
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
            #
            # Tell client that this pre-flight info is valid for 20 days
            #
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain; charset=utf-8';
        add_header 'Content-Length' 0;
        return 204;
    }
    if ($request_method = 'POST') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    }
    if ($request_method = 'GET') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization';
        add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';
    }

【问题讨论】:

  • “但是为什么在使用 postman 使用 API 时它会起作用” - 因为在那种情况下,CORS 甚至不适用...... Postman 不是浏览器,并且因此,一开始就没有实施任何此类限制/遵守“同源政策”。
  • 啊,我明白了!我目前正在查看gist.github.com/Stanback/7145487 来解决这个问题。我还卸载了Allow-Control-Allow-Origin:* 扩展,因为我宁愿修补我的后端而不是这种解决方法

标签: angular symfony cors


【解决方案1】:

我已经设法让它工作了,所以我是这样做的,以供参考:

  1. 删除 nelmio/cors-bundle(因为我们直接使用 NGINX 处理 CORS),因为它会导致类似 2 Allow-Control-Allow-Origin 标头字段的冲突。

  2. 在 nginx.conf 中添加我想要的方法(其余配置与我原来的帖子一样)

    if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Methods' 'HTTP_VERBS, SEPARATED, WITH, COMMAS';

  3. 重建我的 docker 堆栈docker-compose build

  4. 部署它docker-compose up -d
  5. 享受 CORS 支持

您可以在http://github.com/ikamikaz3/docker-symfony 找到我的 maxpou 的 docker-symfony 的分支以获得更深入的信息(配置文件等...) 其中包含一个带有 ELK/Kibana、PhpMyAdmin (WIP) 的 Symfony flex 堆栈,以及现在支持 CORS 的 NGINX!

【讨论】:

    猜你喜欢
    • 2021-02-04
    • 2019-08-28
    • 1970-01-01
    • 2018-05-19
    • 2020-11-30
    • 1970-01-01
    • 2012-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多