Python Falcon 中的 CORS 失败,即使是 Auth Pre-Flight
CORS failure in with Python Falcon even with heads for Auth Pre-Flight
在 Angular2 http.get(url,选项)中使用 OPTIONS 动词 时收到这些错误,即使适当的 CORS headers设置在 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")
对于非 OPTIONS / 正常 http.get() 请求这工作正常。
使用 falcon_cors 解决了这个问题,特别是通过设置 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])
我按照指导试过了by lwcolton on github here
同时设置allow_all_headers
=True, allow_all_methods
=True
即类似于上面的答案 但要添加两个参数
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])
为此,我建议完成 documentation。
此外,resp.set_header('Access-Control-Allow-Origin', '*')
不是在生产中遵循的好习惯。有一些列入白名单的来源和方法,并根据要求,如果来自列入白名单的来源,那么您可以在此处放置相同的来源 resp.set_header('Access-Control-Allow-Origin', req.headers["ORIGIN"])
.
下面是我喜欢的代码-
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
))
完成后,您现在可以将其添加到中间件,例如-
api = falcon.API(middleware=[
CORSMiddleware(),
])
如果您不想使用上述方法,可以继续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,
])
仅供参考,falcon 2.0.0 支持的方法 -
'CONNECT'、'DELETE'、'GET'、'HEAD'、'OPTIONS'、'PATCH'、'POST'、'PUT'、'TRACE'
在 Angular2 http.get(url,选项)中使用 OPTIONS 动词 时收到这些错误,即使适当的 CORS headers设置在 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")
对于非 OPTIONS / 正常 http.get() 请求这工作正常。
使用 falcon_cors 解决了这个问题,特别是通过设置 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])
我按照指导试过了by lwcolton on github here
同时设置allow_all_headers
=True, allow_all_methods
=True
即类似于上面的答案
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])
为此,我建议完成 documentation。
此外,resp.set_header('Access-Control-Allow-Origin', '*')
不是在生产中遵循的好习惯。有一些列入白名单的来源和方法,并根据要求,如果来自列入白名单的来源,那么您可以在此处放置相同的来源 resp.set_header('Access-Control-Allow-Origin', req.headers["ORIGIN"])
.
下面是我喜欢的代码-
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
))
完成后,您现在可以将其添加到中间件,例如-
api = falcon.API(middleware=[
CORSMiddleware(),
])
如果您不想使用上述方法,可以继续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,
])
仅供参考,falcon 2.0.0 支持的方法 -
'CONNECT'、'DELETE'、'GET'、'HEAD'、'OPTIONS'、'PATCH'、'POST'、'PUT'、'TRACE'