Skip to content
This repository has been archived by the owner on Feb 16, 2023. It is now read-only.

Cors not working with POST request with Docker and Nginx #543

Open
stackerito opened this issue Sep 10, 2021 · 3 comments
Open

Cors not working with POST request with Docker and Nginx #543

stackerito opened this issue Sep 10, 2021 · 3 comments

Comments

@stackerito
Copy link

stackerito commented Sep 10, 2021

I am using Docker + Nginx to proxy requests between my frontend React project on localhost to backend Laravel API on localhost:8080.

I try to register a new user from the frontend on localhost/register to Laravel localhost:8080/api/register

The GET request to sanctum/csrf-cookie works and it sets the XSRF-TOKEN

But then I try to send POST request to register a user and I get CORS error:

Cross-Origin Request Blocked: The Same Origin Policy disallows reading
the remote resource at http://localhost:8080/api/register. (Reason:
CORS header ‘Access-Control-Allow-Origin’ is missing)

And despite this message, the user is registered successfully. But the error still appears because indeed the response does not contain the ‘Access-Control-Allow-Origin’ header.

I'm not sure if something in the middle (nginx, docker) is blocking it, but the GET request clearly works because when I try to change the allowed_origins in my cors.php file it throws an error.

This is my cors.php:

    'paths' => ['api/*', 'sanctum/csrf-cookie'],

    'allowed_methods' => ['*'],

    'allowed_origins' => ['http://localhost'],

    'allowed_origins_patterns' => ['*'],

    'allowed_headers' => ['*'],

    'exposed_headers' => [],

    'max_age' => 0,

    'supports_credentials' => true,

This is the OPTIONS response headers:

Status 204 No Content
Version HTTP/1.1
Transferred 494 B (0 B size)
Referrer Policy strict-origin-when-cross-origin

    	
    HTTP/1.1 204 No Content

    Server: nginx/1.20.1

    Content-Type: text/html; charset=UTF-8

    Connection: keep-alive

    X-Powered-By: PHP/8.0.10

    Cache-Control: no-cache, private

    Date: Fri, 10 Sep 2021 11:03:28 GMT

    Access-Control-Allow-Origin: http://localhost

    Vary: Origin, Access-Control-Request-Method, Access-Control-Request-Headers

    Access-Control-Allow-Credentials: true

    Access-Control-Allow-Methods: POST

    Access-Control-Allow-Headers: content-type,x-xsrf-token

    Access-Control-Max-Age: 0

This is the OPTIONS request headers:

Status 204 No Content
Version HTTP/1.1
Transferred 494 B (0 B size)
Referrer Policy strict-origin-when-cross-origin

    	
    Access-Control-Allow-Credentials
    	true
    Access-Control-Allow-Headers
    	content-type,x-xsrf-token
    Access-Control-Allow-Methods
    	POST
    Access-Control-Allow-Origin
    	http://localhost
    Access-Control-Max-Age
    	0
    Cache-Control
    	no-cache, private
    Connection
    	keep-alive
    Content-Type
    	text/html; charset=UTF-8
    Date
    	Fri, 10 Sep 2021 11:07:14 GMT
    Server
    	nginx/1.20.1
    Vary
    	Origin, Access-Control-Request-Method, Access-Control-Request-Headers
    X-Powered-By
    	PHP/8.0.10
    	
    OPTIONS /api/register HTTP/1.1

    Host: localhost:8080

    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0

    Accept: */*

    Accept-Language: en-US,en;q=0.5

    Accept-Encoding: gzip, deflate

    Access-Control-Request-Method: POST

    Access-Control-Request-Headers: content-type,x-xsrf-token

    Referer: http://localhost/

    Origin: http://localhost

    Connection: keep-alive

    Sec-Fetch-Dest: empty

    Sec-Fetch-Mode: cors

    Sec-Fetch-Site: cross-site

This is the POST response headers:

Status 200 OK
Version HTTP/1.1
Transferred 16.68 KB (16.49 KB size)
Referrer Policy strict-origin-when-cross-origin
    	
    HTTP/1.1 200 OK

    Server: nginx/1.20.1

    Date: Fri, 10 Sep 2021 11:09:32 GMT

    Content-Type: text/html; charset=UTF-8

    Transfer-Encoding: chunked

    Connection: keep-alive

    X-Powered-By: PHP/8.0.10
    	
    Accept
    	application/json
    Accept-Encoding
    	gzip, deflate
    Accept-Language
    	en-US,en;q=0.5
    Connection
    	keep-alive
    Content-Length
    	62
    Content-Type
    	application/json
    Cookie
    	XSRF-TOKEN=long-value-here
    Host
    	localhost:8080
    Origin
    	http://localhost
    Referer
    	http://localhost/
    Sec-Fetch-Dest
    	empty
    Sec-Fetch-Mode
    	cors
    Sec-Fetch-Site
    	cross-site
    User-Agent
    	Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0
    X-XSRF-TOKEN long-value-here

This is the POST request headers:

Status 200 OK
Version HTTP/1.1
Transferred 16.68 KB (16.49 KB size)
Referrer Policy strict-origin-when-cross-origin

    	
    HTTP/1.1 200 OK

    Server: nginx/1.20.1

    Date: Fri, 10 Sep 2021 11:09:32 GMT

    Content-Type: text/html; charset=UTF-8

    Transfer-Encoding: chunked

    Connection: keep-alive

    X-Powered-By: PHP/8.0.10
    	
    POST /api/register HTTP/1.1

    Host: localhost:8080

    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:92.0) Gecko/20100101 Firefox/92.0

    Accept: application/json

    Accept-Language: en-US,en;q=0.5

    Accept-Encoding: gzip, deflate

    Content-Type: application/json

    X-XSRF-TOKEN: long-value-here

    Content-Length: 62

    Origin: http://localhost

    Connection: keep-alive

    Referer: http://localhost/

    Cookie: XSRF-TOKEN=long-value-here

    Sec-Fetch-Dest: empty

    Sec-Fetch-Mode: cors

    Sec-Fetch-Site: cross-site

In order to fix this CORS error I added the following to my nginx config:

        set $METHODS  'GET, POST, OPTIONS, HEAD';
        set $HEADERS  'Authorization, Origin, X-Requested-With, Content-Type, Accept';
        
        
        if ( $request_method = POST ){
          add_header 'Access-Control-Allow-Origin' 'http://localhost';
          add_header 'Access-Control-Allow-Credentials' 'true';
        }

    }

So now my nginx config file looks like this:

server {
    listen 8080;
    index index.php index.html;    
    error_log /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
    root /var/www/html/public;
    
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    location ~ \.php$ {        
        try_files $uri = 404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php:9000;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;

        
        set $METHODS  'GET, POST, OPTIONS, HEAD';
        set $HEADERS  'Authorization, Origin, X-Requested-With, Content-Type, Accept';
        
        
        if ( $request_method = POST ){
          add_header 'Access-Control-Allow-Origin' 'http://localhost';
          add_header 'Access-Control-Allow-Credentials' 'true';
        }

    }
    
}

  server {    
    listen       80;       
      location / {      
      proxy_pass      http://node:3000;
      
    }
  }

So manually telling nginx to send back these headers for the POST request work, but why I don't get this issue for GET and OPTIONS?

@stackerito stackerito changed the title Cors not working with POST request Cors not working with POST request with Docker and Nginx Sep 10, 2021
@apteles
Copy link

apteles commented Sep 12, 2021

I've been facing the same, problem.

@jesseyvanofferen
Copy link

I'm getting the same error. I have a POST request that does seem to be processed but still receives a CORS error in the browser.

@christianschoenmakers
Copy link

I'd suggest to read this post about how Laravel is working with a reverse proxy: https://medium.com/weekly-webtips/laravel-and-cors-behind-a-reverse-proxy-b737566bdd96

If you're using Laravel 9, you should change the $proxies variable to '*' in your App/Http/Middleware/TrustProxies.php file

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants