Falcon CORS middleware does not work properly
Asked Answered
P

4

6

I'm using Falcon CORS to allow access to my web service only from several domains. But it does not work properly.

Let me explain, if we take a look at my implementation:

ALLOWED_ORIGINS = ['*']
crossdomain_origin = CORS(allow_origins_list=[ALLOWED_ORIGINS], log_level='DEBUG')

app = falcon.API(middleware=[RequireJSON(), JSONTranslator(), cors.middleware])

When I make any post request to my API service, I get this warning:

Aborting response due to origin not allowed

But, then I get the correct response from my API.
Here is an official docs about this module: https://github.com/lwcolton/falcon-cors

Placatory answered 20/12, 2016 at 16:58 Comment(0)
J
6

Your code does not match the falcon-cors documentation's example:

import falcon
from falcon_cors import CORS    
cors = CORS(allow_origins_list=['http://test.com:8080'])    
api = falcon.API(middleware=[cors.middleware])
#                            ^^^^^^^^^^^^^^^

Note the cors.middleware variable is being passed into the api call. In your code you are creating crossdomain_origin but not passing it into the API setup.

If this does not solve it, please provide a working code example, including the Falcon resource classes, that is easy to test and reproduce, and I'm happy to try to assist.

edit:

From comments below, it sounds like falcon-cors is working properly, rather the problem may be origin header was being omitted from the request.

https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

The Origin header indicates the origin of the cross-site access request or preflight request.

Jetblack answered 20/12, 2016 at 17:24 Comment(7)
Sorry, that's my fault, i make import of crossdomain_origin as cors, so thats mistake only in code example, but not in my projectPlacatory
OK please post a minimal example that reproduces the issue, there is no other way for others to help more.Jetblack
What version of python? What is the contents of the config module? Resources dict is empty- please give a working example. It's not runnable without these things. gist.github.com is sometimes useful too, because you can post multiple files into one gist.Jetblack
if you have a time and you interested in this problem, we can have few minutes skypecall, where i can explain my problem to you more widePlacatory
Sorry I am not able to do that. Please see this for additional help (How to create a Minimal, Complete, and Verifiable example) stackoverflow.com/help/mcveJetblack
I found that if pass to request an http header "origin", i do not get such warning, but i don't get error that origin is not allowedPlacatory
Also helpful: #42715502Antipater
H
4

I tried as guided by lwcolton on github here

And also set allow_all_headers=True, allow_all_methods=True

i.e. same as @Ryan comment

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])
Haemin answered 3/2, 2020 at 9:17 Comment(2)
why use it at all if you're just going to pass everything through?Carew
It is a code base/sample for us to set True/False or go further to set specific ip whitelist laterHaemin
B
1

Side note:

ORIGIN '*' does not work on some browsers.. notably IE. In the past I've had to dynamically set the ORIGIN header to the 'host' name requested in the HTTP headers in order to support a wildcard domain host for a site I setup.

Balladmonger answered 20/3, 2019 at 20:36 Comment(1)
We can forget IE ^^ Irs Edge nowHaemin
J
1

There's is another way to implement this without using falcon-cors

You might want to look at this on the official documentation - how-do-i-implement-cors-with-falcon

class CORSComponent:

    def process_response(self, req, resp, resource, req_succeeded):
        resp.set_header('Access-Control-Allow-Origin', '*')

        if (req_succeeded
            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
            ))

When using the above approach, OPTIONS requests must also be special-cased in any other middleware or hooks you use for auth, content-negotiation, etc. 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.

You can now put this in middleware

api = falcon.API(middleware=[
    CORSComponent()
])
Johnnyjohnnycake answered 20/5, 2020 at 17:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.