API: Allow cross-origin requests

When a REST API is called from within a browser page from a different domain,
the server needs to explicitly allow this. This makes the OctoPrint
API available also to other webapps, for instance those hosted on same network in hackerspace.
This commit is contained in:
Jon Nordby 2014-06-07 00:26:11 +02:00
parent 3ee745d79c
commit 0bd6005cb9

View file

@ -32,6 +32,28 @@ from . import users as api_users
from . import log as api_logs
def optionsAllowOrigin(request):
""" Always reply 200 on OPTIONS request """
resp = current_app.make_default_options_response()
headers = None
if 'ACCESS_CONTROL_REQUEST_HEADERS' in request.headers:
headers = request.headers['ACCESS_CONTROL_REQUEST_HEADERS']
# Allow the origin which made the XHR
resp.headers['Access-Control-Allow-Origin'] = request.headers['Origin']
# Allow the actual method
resp.headers['Access-Control-Allow-Methods'] = request.headers['Access-Control-Request-Method']
# Allow for 10 seconds
resp.headers['Access-Control-Max-Age'] = "10"
# We also keep current headers
if headers is not None:
resp.headers['Access-Control-Allow-Headers'] = headers
return resp
@api.before_request
def beforeApiRequests():
"""
@ -41,6 +63,9 @@ def beforeApiRequests():
the request.
"""
if request.method == 'OPTIONS':
return optionsAllowOrigin(request)
apikey = getApiKey(request)
if apikey is None:
# no api key => 401
@ -66,6 +91,16 @@ def beforeApiRequests():
# invalid api key => 401
return make_response("Invalid API key", 401)
@api.after_request
def afterApiRequests(resp):
""""""
# Allow crossdomain
if request.method != 'OPTIONS' and 'Origin' in request.headers:
resp.headers['Access-Control-Allow-Origin'] = request.headers['Origin']
return resp
#~~ first run setup