1

I am trying to build a simple API with a php backend and a React JS frontend. I am using two separate docker containers for this (api.dev.de and react.dev.de, as it is a requirement. I am using a slightly adapted version of the nginx proxy. However, when I send the request per React fetch() to the server, I get the error:

Access to fetch at 'https: //api.dev.de/index.php?read=users' from origin 'https: //react.dev.de' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.

Below you can see my request that I am trying to make and the .htaccess file.

I already looked up some solutions that worked for others, including this one that I also wrote into my Dockerfile (and first enabling the extension for this image in my docker-compose.yml).

Furthermore I dug through this answer and navigated through those links to other articles to build up some knowledge, but still no success...

Here are my code snippets.

Persons.js:

...

fetch('https://api.dev.de/index.php?read=users', {
      method: 'POST',
      headers: {
        'Authorization': 'Basic ' + btoa("<secretName>:<secretPass>"),
        'Accept': 'application/json',
        'Content-Type': 'application/json',
      }
    })

...

.htaccess:

Authtype Basic
AuthName "Protected section. Only for developers."
AuthUserFile /var/www/html/App/.htpasswd
Require valid-user

Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Credentials "true"

The config in the Dockerfile:

FROM thecodingmachine/php:7.3-v2-apache

...

RUN a2enmod headers

...

When executing the function, I get those console logs:

Access to fetch at 'https:// api.dev.de/index.php?read=users' from origin 'https:// react.dev.de' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.

VM2133:1 POST https://api.dev.de/index.php?read=users net::ERR_FAILED

However, when I delete all authentication config in the .htaccess file as well deleting the Authorization and Content-Type section from the Persons.js file, I get a valid response. But I can't just exclude my authorization from the page.

When I build the React App and paste it in the same docker container as the API and then call it, everything is working fine. So I assume it is the config of the docker container (correct me if I am wrong).

Update:

Since yesterday I tried out different things and came up with one last problem.

My fetch() function now looks like the following:

fetch('https://api.dev.de/index.php?read=users&pass=<password>', {
      method: 'GET',
      headers: {
        'Content-Type': 'multipart/form-data',
        'Accept': 'application/json'
      },
    })

I also changed my .htaccess file:

# Enabled in the Dockerfile but still checking if it is enabled.
<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
    Header set Access-Control-Content-Type "*"
    Header set Access-Control-Accept "*"
    # This should enable the authentication header
    Header set Access-Control-Allow-Credentials "true"
</IfModule>

Now the request works, but when I change the fetch() function to send an authorization header ('Authorization': 'Basic: ' + btoa('<username>:<password>')) and the .htaccess to this:

Authtype Basic
AuthName "Protected section. Only for developers."
AuthUserFile /var/www/html/App/.htpasswd
Require valid-user

<IfModule mod_headers.c>
    Header set Access-Control-Allow-Origin "*"
    Header set Access-Control-Content-Type "*"
    Header set Access-Control-Accept "*"
    # This should enable the authentication header
    Header set Access-Control-Allow-Credentials "true"
</IfModule>

I still get the error:

Access to fetch at 'https://api.dev.de/index.php?read=users&pass=crud_restAPI_call' from origin 'https://react.dev.de' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.

Is this because the order of my .htaccess or do I need to modify something else?

Update 2:

As of my research, I found this answer to a similar issue: "The preflight request (OPTIONS), which is where i encounter the 401 unauthorized. I think this is because I've read that OPTIONS strips out some headers, including the Authentication header, so without that, it can't authenticate".

Source: https://github.com/axios/axios/issues/2076

Checking the developer.mozilla.org guide (https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch#Sending_a_request_with_credentials_included) I wanted to send the credentials always (to get the preflight request to succeed).

However, this does not work...

Has somebody an idea why it doesn't?

Updated fetch() function:

fetch('https://api.dev.de/index.php?read=users&pass=<password>', {
      method: 'POST',
      credentials: 'include',
      headers: {
        'Authorization': 'Basic: ' + btoa('<secretName>:<secretPass>'),
        'Content-Type': 'multipart/form-data',
        'Accept': 'application/json'
      },
    })

I still get the same error:

Access to fetch at 'https://api.dev.de/index.php?read=users&pass=crud_restAPI_call' from origin 'https://react.dev.de' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: 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.

01000101
  • 23
  • 1
  • 2
  • 9
  • In your apache config, you need to add handling for OPTIONS requests. See the answer and explanation at https://stackoverflow.com/a/45559433/441757 – sideshowbarker Oct 15 '19 at 19:00
  • @sideshowbarker I tried that out but nothing changed regarding the output. (sudo nano /etc/apache2/apache2.conf) – 01000101 Oct 16 '19 at 07:09

1 Answers1

0

The preflight requests are not Docker related issue, they are browser-related policy. You're using HTTP headers that trigger the preflight mechanism, "Authorization" header in your case, and doing a cross-origin calls from the domain of your website to the api.dev.de domain.

You can read this article about avoiding preflights.

I would go with just adding an endpoint to your api server that responds to all OPTIONS requests with the appropriate CORS related headers (.e.g, Access-Control-Allow-Origin)

Arik
  • 5,266
  • 1
  • 27
  • 26