corydolphin / flask-cors

Cross Origin Resource Sharing ( CORS ) support for Flask
https://flask-cors.corydolphin.com/
MIT License
877 stars 137 forks source link

How to specify the list of origins? #212

Closed igorvishnevskiy closed 6 years ago

igorvishnevskiy commented 6 years ago

I need to limit access to calls coming from 2 domain names as well as localhost.

I tried following:

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*.domain-one.com, intranet.domain-two.com, 127.0.0.1"}})

And I tried the following:

app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": ["*.domain-one.com", "intranet.domain-two.com", "127.0.0.1"]}})

Receiving exception in both cases:

[2017-11-29 17:01:54,271] ERROR in app: Exception on /myapi/ [POST]
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1982, in wsgi_app
    response = self.full_dispatch_request()
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1615, in full_dispatch_request
    return self.finalize_request(rv)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1632, in finalize_request
    response = self.process_response(response)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask/app.py", line 1856, in process_response
    response = handler(response)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask_cors/extension.py", line 181, in cors_after_request
    set_cors_headers(resp, res_options)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask_cors/core.py", line 236, in set_cors_headers
    headers_to_set = get_cors_headers(options, request.headers, request.method)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask_cors/core.py", line 168, in get_cors_headers
    origins_to_set = get_cors_origins(options, request_headers.get('Origin'))
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask_cors/core.py", line 123, in get_cors_origins
    elif try_match_any(request_origin, origins):
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask_cors/core.py", line 263, in try_match_any
    return any(try_match(inst, pattern) for pattern in patterns)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask_cors/core.py", line 263, in <genexpr>
    return any(try_match(inst, pattern) for pattern in patterns)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/flask_cors/core.py", line 271, in try_match
    return re.match(maybe_regex, request_origin, flags=re.IGNORECASE)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 137, in match
    return _compile(pattern, flags).match(string)
  File "/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/re.py", line 244, in _compile
    raise error, v # invalid expression
error: nothing to repeat

API works when I allow all CORS:

app = Flask(__name__)
CORS(app)

But I need to limit access to calls coming from 2 domain names as well as localhost.

Thank you for your help.

tista3 commented 6 years ago

You have to specify schema and port if it is not explicit port for that schema. So this do not work with CORS: "origins": ["localhost", "mywebsite.example.com"] And this do work correctly: "origins": ["http://localhost:8000", "http://mywebsite.example.com"]

ghost commented 6 years ago

Can someone please provide an example of using regular expressions to specify access to specific domains. I have tried the following without success: cors = CORS(app, origins=['http://localhost:5000',r'^https://.+example.com$'])

I expect the following URL be allowed access for CORS: https://jan.flan.example.com I also tried variations thereof without success. Thank you

corydolphin commented 6 years ago

@MeesterMan your configuration is correct. The regex detection worked incorrectly for your pattern, and I will update it shortly.

corydolphin commented 6 years ago

Fixed and released as 3.0.5

peterlada commented 5 years ago

@ghost you might want to escape the dot in example.com

Alex-ley-scrub commented 1 year ago

@corydolphin how do you detect if each item in the origins list[str] is an exact match or a regex pattern? Maybe as a follow up, can we pass in patterns that have already been compiled with re.compile(...)?

corydolphin commented 1 year ago

@corydolphin how do you detect if each item in the origins list[str] is an exact match or a regex pattern? Maybe as a follow up, can we pass in patterns that have already been compiled with re.compile(...)?

https://github.com/corydolphin/flask-cors/blob/master/flask_cors/core.py#L254

This API is problematic in retrosepct, but this is how/where it is inferred.