CORS Headers problems

Hello,

I have a very strange problem, only on safari.

I have set up cross-origin access on my api, and it doesn't only work on safari. More exactly, if during the call I do not pass headers, it works:

fetch('https://api.myapp.com/api/safari-test')
200 OK

Access-Control-Allow-Methods: GET,OPTIONS
Access-Control-Allow-Origin: https://www.myapp.com
Access-Control-Allow-Headers: Accept,Accept-Encoding,Accept-Language,Access-Control-Request-Header,Access-Control-Request-Method,Authorization,Cache-Control,Connection,Content-Type,DNT,Host,If-Modified-Since,Keep-Alive,Origin,Pragma,Referer,User-Agent,x-csrf-token,x-requested-with

Content-Type: application/json; charset=UTF-8
Content-Encoding: gzip
Date: Thu, 23 Sep 2021 16:32:00 GMT
Vary: Accept-Encoding, Origin
Server: nginx

But if I pass headers, it doesn't work anymore:

fetch('https://api.myapp.com/api/safari-test', {
    method: 'GET',
    headers: new Headers({
         'Authorization' : 'Bearer ...'
    }),
    mode: 'cors',
    cache: 'default'
})
[err] Fetch API cannot load https://api.myapp.com/api/safari-test due to access control checks.

I don't understand why, all the necessary headers are transmitted. Here is my nginx configuration:

location ~ ^/api/safari-test {
    set $cors '';

    if ($http_origin ~ ^(https?:\/\/www\.myapp\.com)$) {
        set $cors 'true';
    }
    if ($request_method = 'OPTIONS') {
        set $cors "${cors}options";
    }
    if ($request_method = 'GET') {
        set $cors "${cors}get";
    }
    if ($cors = "true") { 
        add_header 'Access-Control-Allow-Origin' "$http_origin" always; 
        add_header 'Vary' Origin always; 
    }
    
    if ($cors = "trueget") {
        add_header 'Access-Control-Allow-Origin' "$http_origin" always;
        add_header 'Access-Control-Allow-Methods' 'GET,OPTIONS' always;
        add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Encoding,Accept-Language,Access-Control-Request-Header,Access-Control-Request-Method,Authorization,Cache-Control,Connection,Content-Type,DNT,Host,If-Modified-Since,Keep-Alive,Origin,Pragma,Referer,User-Agent,x-csrf-token,x-requested-with' always;
        add_header 'Vary' Origin always;
    }
    if ($cors = "trueoptions") { 
        add_header 'Connection' 'keep-alive' always; 
        add_header 'Access-Control-Allow-Origin' "$http_origin" always; 
        add_header 'Access-Control-Allow-Methods' 'GET,OPTIONS' always; 
        add_header 'Access-Control-Allow-Headers' 'Accept,Accept-Encoding,Accept-Language,Access-Control-Request-Header,Access-Control-Request-Method,Authorization,Cache-Control,Connection,Content-Type,DNT,Host,If-Modified-Since,Keep-Alive,Origin,Pragma,Referer,User-Agent,x-csrf-token,x-requested-with' always; 
    
        add_header 'Access-Control-Max-Age' 3600 always; 
        add_header 'Content-Type' 'text/plain charset=UTF-8' always; 
        add_header 'Content-Length' 0 always; 
        add_header 'Vary' Origin always; 
    
        return 204; 
    }

    fastcgi_split_path_info ^(.+\.php)(/.+)$;
    
    fastcgi_read_timeout 60s;
    fastcgi_pass unix:/run/php/php7.3-fpm.sock; 
    fastcgi_index micro.php; 
    fastcgi_param APP_ENV production; 
    include fastcgi_params; 
    fastcgi_param SCRIPT_FILENAME $document_root/micro.php; 
    fastcgi_param SCRIPT_NAME     micro.php;
}

Thanks to anyone for an idea for a solution !!!

Answered by ark4ne in 823665022

And years later... I found the problem:

        add_header 'Connection' 'keep-alive' always; 

Remove these resolve my problem.

I ran into this exact problem and got it working. I'll be honest, I don't know why it works, and I don't know what combination of what I did lead to it working. But at least this worked for me.

First, my fetch looked like this

        const resp = await fetch(`URL`, {
          method: "GET",
          credentials: "include",
          headers: {
            Authorization: `STRING`,
          },
          mode: "cors",
        });

Then specifically, in nginx, in the headers for the pre-flight OPTIONS, I removed these

                add_header 'Content-Type' 'text/plain; charset=utf-8' always;
                add_header 'Content-Length' 0 always;

And my allowed headers were these

                add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range,Authorization, Content-Language, Accept, Accept-Language' always;

Best of luck to anyone encountering this in the future. This was found through trial and error, with complete opacity into the inner workings of safari.

Accepted Answer

And years later... I found the problem:

        add_header 'Connection' 'keep-alive' always; 

Remove these resolve my problem.

CORS Headers problems
 
 
Q