I have an API written in python/flask and I want to allow only a couple URLs to access this API. The JavaScript call is trivial jQuery, like:
$.ajax({
url: "http://myApi.com/api/doit",
dataType:'JSON',
success:function(data){
console.log("DEBUG: yeeeeaaaahhh!");
},
error:function(xhr){
console.log("Error occured! status: " + xhr.status + ", text: " + xhr.statusText);
}
});
Most of the solutions mainly here are pretty disappointing always offering to set Access-Control-Allow-Origin : '*'
or to start chrome disabling the check. Of course it works, but this is not the purpose.
The spec on w3 says a semicolon separated list should work, but it doesn't. Also comma separated list failed.
From flask itself there is http://flask.pocoo.org/snippets/56/ but it does not work with multiple URLs. In the comments there is a suggestion: h.extend([("Access-Control-Allow-Origin", orig) for orig in origin])
but it still does not work.
The only solution I have is to check in code the origin and in case it is in my white list to put in the header Access-Control-Allow-Origin : '*'
. This is a workaround but I don't like it that much. Can you suggest a more elegant solution?
This is typical scenario when working locally with multiple instances of the same frontend project accessing together to a local Flask server, and when the wildcard "*" is not allowed because you are allowing credentials (i.e. using a JWT authentication).
My approach - in development - is to use the after_request decorator and Flask's request context.
Create a domain whitelist:
white = ['http://localhost:8080','http://localhost:9000']
Now use the after_request
decorator to intercept all incoming requests, check if the referrer is in your whitelist and, if it is, inject the response.headers
to allow access to the origin. For example:
from flask import request
@app.after_request
def add_cors_headers(response):
r = request.referrer[:-1]
if r in white:
response.headers.add('Access-Control-Allow-Origin', r)
response.headers.add('Access-Control-Allow-Credentials', 'true')
response.headers.add('Access-Control-Allow-Headers', 'Content-Type')
response.headers.add('Access-Control-Allow-Headers', 'Cache-Control')
response.headers.add('Access-Control-Allow-Headers', 'X-Requested-With')
response.headers.add('Access-Control-Allow-Headers', 'Authorization')
response.headers.add('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, DELETE')
return response
Simple example,try it!
I hope it will help you.
You need to edit white_origin for 'Access-Control-Allow-Origin'.
app_name.py (Python file of Flask )
from flask import request
@app.after_request
def after_request(response):
white_origin= ['http://www.dom.com:8000','http://localhost']
if request.headers['Origin'] in white_origin:
response.headers['Access-Control-Allow-Origin'] = request.headers['Origin']
response.headers['Access-Control-Allow-Methods'] = 'PUT,GET,POST,DELETE'
response.headers['Access-Control-Allow-Headers'] = 'Content-Type,Authorization'
return response
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With