CORS failure in with Python Falcon even with heads for Auth Pre-Flight

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.

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])

Simple way to allow all CORS / OPTIONS requests? � Issue #1220 , CORS failure in with Python Falcon even with heads for Auth Pre-Flight not allowed by Access-Control-Allow-Headers in preflight response. Dismiss Join GitHub today. GitHub is home to over 50 million developers working together to host and review code, manage projects, and build software together.

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])

feat(api): Add CORS support � Issue #609 � falconry/falcon � GitHub, I'm wanting to open the door wide to all CORS requests to my application. I can see there is an additional Falcon/CORS middleware project but� For example, you will typically skip auth for preflight requests because it is simply unnecessary; note that such request do not include the Authorization header in any case. For more sophisticated use cases, have a look at Falcon add-ons from the community, such as falcon-cors, or try one of the generic WSGI CORS libraries available on PyPI. If you use an API gateway, you might also look into what CORS functionality it provides at that level.

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'

[PDF] Falcon Documentation, responding to a preflight request it will approve any headers. requested by the client containing a Python regular expression matching origins. for which the you specify 'Auth-Key' in allow_headers_list, it will be allowed for all. methods We must always set 'Vary: Origin' even if the Origin header is not set,. # Otherwise � CORS support site. CORS on Nginx. The following Nginx configuration enables CORS, with support for preflight requests.

Reason: CORS request external redirect not allowed, Falcon is a reliable, high-performance Python web framework for description = ('The provided auth token is not valid. ' particular book use the Django framework and even JavaScript, but For now, run the tests again and watch to make sure they fail. NOTE(kgriffs): This is a CORS preflight request. A CORS request from an origin domain may consist of two separate requests: A preflight request, which queries the CORS restrictions imposed by the service. The preflight request is required unless the request method is a simple method, meaning GET, HEAD, or POST. The actual request, made against the desired resource. Preflight request

Getting to know Cross-Origin Resource Sharing (CORS), The CORS request was responded to by the server with an HTTP of https:// anotherservice.net/getdata , the CORS request will fail in this� Teams. Q&A for Work. Stack Overflow for Teams is a private, secure spot for you and your coworkers to find and share information.

[PDF] NASA Aeronautics Book Series, “Cross-origin resource sharing (CORS) is a mechanism that allows many In browser terms, this is known as a “pre-flight” request and is often attempted to ASCII lowercase (even when one or more are a simple header). the pre-flight was failing because the resource server had authentication enabled� import falcon from falcon_auth import FalconAuthMiddleware, BasicAuthBackend, TokenAuthBackend # a loader function to fetch user from username, password user_loader = lambda username, password: { 'username': username} # basic auth backend basic_auth = BasicAuthBackend (user_loader) # Auth Middleware that uses basic_auth for authentication auth

Comments
  • Looks like these OPTIONS requests from Angular need to be appropriately handles by falcon? stackoverflow.com/questions/6660019/…
  • Same issue for me. I have to set all to True for allow_origins_list , allow_all_methods, allow_all_headers
  • +1. I used public_cors = CORS(allow_all_origins=True) as shown in github.com/lwcolton/falcon-cors