Reputation: 227
Receiving these error when using the OPTIONS verb in Angular2 http.get(url, options), even though the appropriate CORS headers are set in Falcon Rest API.
XMLHttpRequest cannot load http://localhost:8000/names. Request header field Authorization is not allowed by Access-Control-Allow-Headers in preflight response.
resp.set_header("Access-Control-Allow-Origin", "*")
resp.set_header("Access-Control-Allow-Credentials", "true")
resp.set_header("Access-Control-Allow-Methods", "GET,HEAD,OPTIONS,POST,PUT")
resp.set_header("Access-Control-Allow-Headers",
"Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers")
For non OPTIONS / normal http.get() requests this works fine.
Upvotes: 5
Views: 2788
Reputation: 1194
I'll suggest to go through documentation for this.
Also, resp.set_header('Access-Control-Allow-Origin', '*')
is not a good practice to follow in production. Have some whitelisted origins and methods and based on the request, if coming from whitelisted origin then you can put the same origin in here resp.set_header('Access-Control-Allow-Origin', req.headers["ORIGIN"])
.
Below is the code I prefer-
whitelisted_origins = ["http://localhost:4200"]
whitelisted_methods = ["GET", "POST", "OPTIONS"]
class CORSComponent:
def process_request(self, req, resp):
success = False
# validate request origin
if ("ORIGIN" in req.headers):
# validate request origin
if (req.headers["ORIGIN"] in whitelisted_origins):
# validate request method
if (req.method in whitelisted_methods):
success = True
else:
# you can put required resp.status and resp.media here
pass
else:
# you can put required resp.status and resp.media here
pass
else:
# you can put required resp.status and resp.media here
pass
if success:
resp.set_header('Access-Control-Allow-Origin', req.headers["ORIGIN"])
else:
# exit request
resp.complete = True
def process_response(self, req, resp, resource, req_succeeded):
if (req_succeeded and
"ORIGIN" in req.headers and
and req.method == 'OPTIONS'
and req.get_header('Access-Control-Request-Method')
):
# NOTE: This is a CORS preflight request. Patch the response accordingly.
allow = resp.get_header('Allow')
resp.delete_header('Allow')
allow_headers = req.get_header(
'Access-Control-Request-Headers',
default='*'
)
resp.set_headers((
('Access-Control-Allow-Methods', allow),
('Access-Control-Allow-Headers', allow_headers),
('Access-Control-Max-Age', '86400'), # 24 hours
))
Once done, you can now add this to middleware like-
api = falcon.API(middleware=[
CORSMiddleware(),
])
If you do not wish to use the above method, you can go ahead with falcon-cors.
from falcon_cors import CORS
cors = CORS(
# allow_all_origins=False,
allow_origins_list=whitelisted_origins,
# allow_origins_regex=None,
# allow_credentials_all_origins=True,
# allow_credentials_origins_list=whitelisted_origins,
# allow_credentials_origins_regex=None,
allow_all_headers=True,
# allow_headers_list=[],
# allow_headers_regex=None,
# expose_headers_list=[],
# allow_all_methods=True,
allow_methods_list=whitelisted_methods
)
api = falcon.API(middleware=[
cors.middleware,
])
FYI, Methods supported by falcon 2.0.0 -
'CONNECT', 'DELETE', 'GET', 'HEAD', 'OPTIONS', 'PATCH', 'POST', 'PUT', 'TRACE'
Upvotes: 1
Reputation: 35384
I tried as guided by lwcolton on github here
And also set allow_all_headers
=True, allow_all_methods
=True
i.e. similar to above answer https://stackoverflow.com/a/42716126/248616 but two more params to add
from falcon_cors import CORS
cors = CORS(
allow_all_origins=True,
allow_all_headers=True,
allow_all_methods=True,
)
api = falcon.API(middleware=[cors.middleware])
Upvotes: 1
Reputation: 227
Resolved this using falcon_cors, specifically by setting allow_all_methods=True
pip install falcon-cors
from falcon_cors import CORS
cors = CORS(allow_origins_list=['http://localhost:3000'],
allow_all_headers=True,
allow_all_methods=True)
api = falcon.API(middleware=[cors.middleware])
Upvotes: 7