Symfony 4.1 - CORS issue

Viewed 5868

I have some issue with my symfony 4.1 API:

I'm consuming my API through a ionic application using angular httpclient.

My problem is with the CORS headers especially Access-Control-Allow-Methods

I've had problems with CORS since my API and my application aren't on the same origin which made my install nelmio/cors-bundle to handle CORS.

My nelmio_cors.yaml is as following:

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

This actually works for all the methods i was using since then:

  • Post requests [OK]
  • Get requests [OK]
  • Delete requests [OK]

Now i wanted to add a PATCH route to my API. I've testing the controller with Postman and i works like a charm. Now when i query the same route from my angular service :

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

The console logs the following:

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

Here you can see the response headers of the request:

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

As you can see and if i understand CORS headers correctly, PATCH methods aren't allowed but then why does it works when using postman to consume the API.

I've also installed chrome's Allow-Control-Allow-Origin:* extension but no success there aswell...

I'm using https://github.com/ikamikaz3/docker-symfony as my stack could it come from there ? (misconfiguration somewhere maybe?)

I can provide more code if required but it seems like a stupid mistake to me...

EDIT 1 :

After uninstalling Allow-Control-Allow-Origin:* from chrome i get the following on login

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.

EDIT 2:

After updating my symfony.conf with the following inside my nginx container, i managed to get the API to work, PATCH still broken tho but i think i can do it <3

    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';
    }
1 Answers

I've managed to get this to work so here's how i did it for reference:

  1. Remove nelmio/cors-bundle (since we handle CORS directly with NGINX), because it caused conflits like 2 Allow-Control-Allow-Origin header field.

  2. Add the methods i want in nginx.conf (with the rest of the config as in my original post)

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

  3. Rebuild my docker stack docker-compose build

  4. Deploy it docker-compose up -d
  5. Enjoy CORS support

You can find my fork of maxpou's docker-symfony for more in depth informations (config files etc...) at http://github.com/ikamikaz3/docker-symfony which contains an Symfony flex stack with ELK/Kibana, PhpMyAdmin (WIP), and now NGINX with CORS support !!

Related