Skip to content
This repository was archived by the owner on Feb 16, 2023. It is now read-only.
This repository was 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

Description

@stackerito

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?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions