Comments (6)
Extending adaptor looks better.
Sorry, the library is underpowered.
I know there are several bug reports that are not fixed yet.
The library initial author is retired, I have a limited spare time that I spend mostly on asyncio and aiohttp.
If somebody wants to maintain the project -- you are welcome!
from aiohttp-cors.
As i see, for preflight CORS requests it is enough to return non-200 response to deny user request.
It is possible to extend views from both aiohttp.web.View
and aiohttp_cors.CorsViewMixin, and re-define _get_config(self, request, origin, request_method)
method. If origin is not passing custom checks - raise KeyError
exception, otherwise call super()._get_config(). KeyError
would lead for 403 Forbidden response:
class BaseHandler(aiohttp.web.View, aiohttp_cors.CorsViewMixin):
async def _get_config(self, request, origin, request_method):
# Handle pre-flight requests
if not origin_is_allowed(origin):
raise KeyError # would cause 403 Forbidden response
return super()._get_config(request, origin, request_method)
As for non-preflight requests, to deny user request we should not add CORS headers and i don't see easy implementation.
There is _CorsConfigImpl._on_response_prepare
method, that is supposed to set appropriate CORS headers to allow request or do nothing (there are several return
rows, that prevent CORS headers installation) to deny.
But it is internal object - it is hard-coded in CorsConfig.__init__ method
.
It is possible to extend both CorsConfig and _CorsConfigImpl, add unified (both for preflight and for non-preflight requests) hook to _CorsConfigImpl._on_response_prepare.
What do you think? What is the best way to implement additional origin checks?
from aiohttp-cors.
I think yes, overriding _get_config()
is legitimate here.
from aiohttp-cors.
@asvetlov, thank you. And what is the correct way for preflight requests? Is the only way to implement checks - to extend _CorsConfigImpl._on_response_prepare()
and CorsConfig.__init__()
(to replace hard-coded _CorsConfigImpl
)?
from aiohttp-cors.
Hmm, hacking _CorsConfigImpl
smells ugly.
Ideally _CorsConfigImpl._on_response_prepare()
should be not changed but cors configuration.
Could you share your code to demonstrate why do you do it and what _on_response_prepare()
lines are changed?
from aiohttp-cors.
Thank you for fast response.
My first idea was to do something like that:
class _CustomCorsConfigImpl(_CorsConfigImpl):
@staticmethod
def check_origin_allowed(origin: str) -> bool:
# Do origin checks
return True
async def _on_response_prepare(self,
request: web.Request,
response: web.StreamResponse):
# Terminate CORS if origin is not allowed
if not self.check_origin_allowed(request.headers.get(hdrs.ORIGIN)):
return
return super()._on_response_prepare(request, response)
But later i found that it is much easier to extend ResourcesUrlDispatcherRouterAdapter
class.
It can affect both preflight and non-preflight responses behavior:
class CustomResourcesUrlDispatcherRouterAdapter(ResourcesUrlDispatcherRouterAdapter):
def __init__(self, *args, allowed_origin_patterns: Collection[re.Pattern], **kwargs):
self.allowed_origin_patterns = allowed_origin_patterns
super().__init__(*args, **kwargs)
def check_origin_allowed(self, origin: str) -> bool:
for allowed_origin_pattern in self.allowed_origin_patterns:
if allowed_origin_pattern.match(origin):
return True
return False
async def get_preflight_request_config(
self,
preflight_request: web.Request,
origin: str,
requested_method: str):
# Do origin checks
if not self.check_origin_allowed(origin):
# raising web.HTTPForbidden seems not a very good idea here
raise KeyError
return super().get_preflight_request_config(preflight_request, origin,
requested_method)
def get_non_preflight_request_config(self, request: web.Request):
# Do origin checks and return empty config {} if checks are not passed
if not self.check_origin_allowed(request.headers.get(hdrs.ORIGIN)):
return {}
return super().get_non_preflight_request_config(request)
also, it is possible to configure aiohttp_cors with custom ResourcesUrlDispatcherRouterAdapter class easily:
cors_defaults = {
"*": aiohttp_cors.ResourceOptions(
allow_credentials=True,
expose_headers="*",
allow_headers="*",
),
}
app['aiohttp_cors'] = CorsConfig(
app,
defaults=cors_defaults,
router_adapter=CustomResourcesUrlDispatcherRouterAdapter(
app.router, cors_defaults,
allowed_origin_patterns=[re.compile('[a-z0-9_-]+.example.com$')],
)
)
That seem be not so ugly and does not use internal api.
from aiohttp-cors.
Related Issues (20)
- Wildcard ports for localhost HOT 5
- method '*' treated differently from others HOT 9
- Cors and IOS Safari HOT 3
- Only 1 is allowed HOT 1
- thx for password and key to pypi HOT 1
- Python 3.8 test_static_resource failure: TypeError: issubclass() arg 1 must be a class
- DeprecationWarnings with Python 3.8: "@coroutine" decorator
- cant import aiohttp_cors HOT 1
- python3.7 HOT 3
- Does this project follow semver? HOT 1
- Dependabot couldn't authenticate with https://pypi.python.org/simple/
- Routing hierarchy confusion with CORs
- Should aiohttp-cors add a Vary: Origin when emitting a access-control-allow-origin? HOT 1
- 0.7.0 + master: pytest is failing HOT 2
- Is it possible to return `Access-Control-Allow-Origin: *` in response to preflight request instead of existing `Origin` header?
- Regex domains
- Lets through Postman / Curl requests HOT 2
- Let's put `aiohttp-cors` under the `aio-libs` org on PyPI
- How can I enforce CORS despite middlewares?
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from aiohttp-cors.