nelmio/NelmioCorsBundle

400 Bad request on Preflight (CORS Preflight Did Not Succeed) - Symfony 4

marouanemaous opened this issue · 4 comments

Hello everyone,

I've been blocked by this problem for some time now.

I'm doing a simple JavaScript XHR request to an api in my symfony project.

I appreciate the help.

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

Request Headers :

OPTIONS /api/findplacefromtext/sometext/AIzaSyCfaefrzgefzrg34fez38hiI_zo HTTP/1.1
Host: localhost:8000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:88.0) Gecko/20100101 Firefox/88.0
Accept: /
Accept-Language: fr,fr-FR;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Access-Control-Request-Method: GET
Access-Control-Request-Headers: access-control-allow-headers,access-control-allow-origin,content-type
Referer: http://localhost:8001/
Origin: http://localhost:8001
Connection: keep-alive

Response headers :

HTTP/1.1 400 Bad Request
Access-Control-Allow-Headers: content-type, authorization
Access-Control-Allow-Methods: GET, OPTIONS, POST, PUT, PATCH, DELETE
Access-Control-Allow-Origin: http://localhost:8001
Access-Control-Max-Age: 3600
Cache-Control: no-cache, private
Content-Type: text/html; charset=UTF-8
Date: Sun, 25 Apr 2021 17:57:13 GMT
Vary: Origin
X-Debug-Token: 4eede2
X-Debug-Token-Link: http://localhost/_profiler/4eede2
X-Powered-By: PHP/7.3.24-(to be removed in future macOS)
X-Robots-Tag: noindex
Content-Length: 48

Maybe it is because the route error? Have you try it in postman or insomnia?

It's works fine from postman. But when I call the API from JavaScript I get the PreFlightInvalidStatus

Content-Length: 48

With this information, I think that your help will be found in the body of the response.

And it's weird to see that : access-control-allow-headers,access-control-allow-origin in your Access-Control-Request-Headers on the request header.

LBeckX commented

Have the same problem.
If I return a

return $this->json(['error' => '400'], Response::HTTP_BAD_REQUEST);

Then i get the response in the browser:

Access to fetch at ''https://my-api-host/my/post' from origin 'https://my-frontend-host' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

It seems that in the error response the 'Access-Control-Allow-Origin' header is missing.

I have the following configuration in the NelmioCorsBundle:

nelmio_cors:
    defaults:
        origin_regex: true
        allow_origin: [ '%env(CORS_ALLOW_ORIGIN)%' ]
        allow_methods: [ 'GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE' ]
        allow_headers: [ '*' ]
        expose_headers: [ 'Link' ]
        forced_allow_origin_value: ~
        skip_same_as_origin: true
        max_age: 3600
    paths:
        '^/api/':
            allow_origin: [ '*' ]
            allow_headers: [ '*' ]
            allow_methods: [ 'GET', 'OPTIONS', 'POST', 'PUT', 'PATCH', 'DELETE' ]
            forced_allow_origin_value: ~
            max_age: 3600

I use the following packages:

"nelmio/cors-bundle": "^2.3", -> 2.3.1

"symfony/framework-bundle": "6.3.*", -> 6.3.4

Or do you think this is an nginx problem?
My NGINX Config is the following in a docker container:


server {
    listen 80 default_server;

    index index.php;
    server_name _;
    server_tokens off;
    root /srv/app/public;

    client_max_body_size 100M;

    location / {
        try_files $uri /index.php$is_args$args;

        if ($request_method = 'OPTIONS') {
                add_header 'Access-Control-Allow-Origin' '*';
                add_header 'Access-Control-Allow-Credentials' 'true';
                add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS, POST, PUT, OPTIONS';
                add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,authorization';
                add_header 'Access-Control-Max-Age' 1728000;
                add_header 'Content-Type' 'text/plain charset=UTF-8';
                add_header 'Content-Length' 0;
                return 204;
        }
    }

    location ~ ^/index\.php(/|$) {
        fastcgi_pass 127.0.0.1:9000;
        fastcgi_split_path_info ^(.+\.php)(/.*)$;
        include fastcgi_params;
        fastcgi_param APP_CONTEXT api;

        fastcgi_param SCRIPT_FILENAME $realpath_root$fastcgi_script_name;
        fastcgi_param DOCUMENT_ROOT $realpath_root;

        internal;
    }

    location ~ \.php$ {
        return 404;
    }

    error_log /var/log/nginx/project_error.log;
    access_log /var/log/nginx/project_access.log;
}