I have a Flask application that is behind an Apache server. I need to connect to it from a frontend that will be on
another host (and currently is on localhost).
In Flask I’ve added the following line to support CORS:
CORS(app, origins=["http://localhost:3000"], supports_credentials=True)
In httpd.conf I’ve also set the headers with the following code:
Header always set Access-Control-Allow-Origin "http://localhost:3000"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, DELETE, PUT"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
Header always set Access-Control-Expose-Headers "Content-Security-Policy, Location"
Header always set Access-Control-Allow-Credentials "true"
# lines below wasn't added now, but I can't get rid of them
AuthType Basic
AuthName "Apache2 QA authorization"
AuthBasicProvider file
AuthUserFile /root/htpasswd
Require valid-use
My Javascript looks as follows:
fetch("https://my-app.com/api/v1/basic/", {
headers: {
'Authorization': 'Basic base64-credentials',
},
mode: "cors",
method: "get"
})
.then(response => response.json())
.then(data => {
console.log(data);
}).catch(error => {
console.log(error);
return [];
});
When I run the code in browser (Firefox), I get the following error:
CORS Allow Origin Not Matching Origin
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://my-app.com/api/v1/basic/. (Reason: CORS preflight response did not succeed). Status code: 401.
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://my-app.com/api/v1/basic/. (Reason: CORS request did not succeed). Status code: (null).
The request headers are:
OPTIONS /api/v1/basic/ HTTP/1.1
Host: my-app.com
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:99.0) Gecko/20100101 Firefox/99.0
Accept: */*
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Access-Control-Request-Method: GET
Access-Control-Request-Headers: authorization
Referer: http://localhost:3000/
Origin: http://localhost:3000
Connection: keep-alive
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
Pragma: no-cache
Cache-Control: no-cache
And the response headers:
HTTP/1.1 401 Unauthorized
Date: Fri, 22 Apr 2022 11:40:46 GMT
Server: Apache
Access-Control-Allow-Origin: http://localhost:3000
Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
Access-Control-Allow-Headers: x-requested-with, Content-Type, origin, authorization, accept, client-security-token
Access-Control-Expose-Headers: Content-Security-Policy, Location
Access-Control-Allow-Credentials: true
WWW-Authenticate: Basic realm="Apache2 QA authorization"
Content-Length: 381
Keep-Alive: timeout=15, max=100
Connection: Keep-Alive
Content-Type: text/html; charset=iso-8859-1
The /basic
endpoint is very simple, and requires no auth from Flask (Apache has its separate auth requirement):
@api.route("/basic")
class SimpleResponse(Resource):
def get(self):
return {"message": "OK"}
I don’t understand what’s wrong here. The request origin matches Access-Control-Allow-Origin
, but still gets rejected.
Also, I have no idea why the Authorization
header is not sent with the request. What am I doing wrong?