Usage¶
There are several ways you can implement CORS support into your Watson project.
- Managed via @decorators in your controllers
- Managed via route definitions
- Managed via event listeners
Default Configuration¶
These configuration options are passed by default into your decorators or listeners.
defaults = {
'allow_origin': None,
'allow_credentials': False,
'allow_methods': (
'DELETE',
'GET',
'OPTIONS',
'PATCH',
'POST',
'PUT',
),
'allow_headers': (
'accept',
'accept-encoding',
'authorization',
'content-type',
'dnt',
'origin',
'user-agent',
'x-csrftoken',
'x-requested-with',
),
'expose_headers': None,
'max_age': 86400,
}
For acceptable values for each of these, please read https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
Option Types¶
- allow_origin
- list|string: The allowed origin(s) for the request
- allow_credentials
- boolean: Whether or not credentials are allowed
- allow_methods
- list: The HTTP request methods that are allowed
- allow_headers
- list: The HTTP headers that are allowed
- expose_headers
- list: The HTTP headers which should be exposed
- max_age
- integer: The length of time in seconds the OPTIONS response can be cached
Configuration Fallbacks¶
Whenever the listener or decorator is invoked, the following order of inheritance of options will be used when processing the request:
- The default configuration (watson.cors.config.defaults)
- The application configuration
- The route configuration (specify the arguments in the options
- property)
- The decorator arguments
Dynamic Allowed Origins¶
The preferred way to approach this issue would be to subclass watson.cors.listeners.Request and then modify the arguments that are sent through to watson.cors.utils.process_cors.
Configuring CORS¶
In addition to the individual ways to configure CORS, you can also take advantage of the way the configuration is inherited, and define common values in your application configuration.
# config.py
cors = {
'allow_origin': 'http://127.0.0.1',
'allow_credentials': True
}
Via Decorators¶
# controllers.py
from watson.cors.decorators import cors
from watson.framework import controllers
from watson.framework.views.decorators import view
class MyController(controllers.Rest):
@view(format='json')
@cors(allow_origin='http://127.0.0.1', allow_credentials=True)
def GET(self):
pass
@cors(allow_origin='http://127.0.0.1', allow_credentials=True)
def OPTIONS(self):
return self.response
If you have already set the options in your application configuration, you can simply decorate the method with @cors.
Via Event Listener¶
# config.py
cors = {
'allow_origin': 'http://127.0.0.1',
'allow_credentials': True
}
events = {
events.DISPATCH_EXECUTE: [
('watson.cors.listeners.Request',)
]
}
Via Routes¶
Routes modify the allow_methods option in a slightly different way to the other ways of configuring CORS. Any items set in the accepts property will override allow_methods.
# config.py
routes {
'allow_origin': 'http://127.0.0.1',
'allow_credentials': True
}
events = {
events.DISPATCH_EXECUTE: [
('watson.cors.listeners.Request',)
]
}
routes = {
'cors-request': {
'path': '/cors',
'options': {
'controller': 'app.controllers.CorsRequest',
'cors': {
'expose_headers': ('my-custom-header',)
}
},
'accepts': ('GET', 'OPTIONS')
},
}