如何在同一应用程序中为处理程序和基于类的视图设置CORS

时间:2019-01-24 15:59:26

标签: python cors aiohttp

目标: 我正在尝试使用aiohttp_cors库在基于aiohttp的Web应用程序中为资源设置CORS。我的应用程序有很多路由,其中​​一些只是普通的协程,但有些是Class Based Views(我们正在转向基于类的视图,但目前处于混合状态)。对于CORS设置,请参阅aiohttp和aiohttp-cors文档。

问题: 访问/api/v1/users时,服务器上的此堆栈跟踪得到空响应

Traceback (most recent call last):
File "/usr/local/lib/python3.7/site-packages/aiohttp/web_protocol.py", line 410, in start
     await resp.prepare(request)
   File "/usr/local/lib/python3.7/site-packages/aiohttp/web_response.py", line 299, in prepare
     await request._prepare_hook(self)
   File "/usr/local/lib/python3.7/site-packages/aiohttp/web_request.py", line 712, in _prepare_hook
     await app.on_response_prepare.send(self, response)
   File "/usr/local/lib/python3.7/site-packages/aiohttp/signals.py", line 35, in send
     await receiver(*args, **kwargs)  # type: ignore
   File "/usr/local/lib/python3.7/site-packages/aiohttp_cors/cors_config.py", line 157, in _on_response_prepare
     config = self._router_adapter.get_non_preflight_request_config(request)
   File "/usr/local/lib/python3.7/site-packages/aiohttp_cors/urldispatcher_router_adapter.py", line 315, in get_non_preflight_request_config
     request, request.method)
   File "/usr/local/lib/python3.7/site-packages/aiohttp_cors/mixin.py", line 23, in get_request_config
     raise ValueError("aiohttp-cors is not configured.")

协同处理程序

# /api/role.py
from models import Role
from aiohttp.web_response import json_response


class RoleHandler:

    def register(self, app):
        app.router.add_get('/roles', self.get_roles)

    @classmethod
    async def get_roles(cls, request):
        roles = await Role.select_roles()
        return json_response(dict(roles=roles))

基于类的视图

# user.py
from aiohttp import web
from aiohttp_cors import CorsViewMixin
from models import User

class UsersCollectionView(web.View, CorsViewMixin):

    async def get(self):
        users = await User.select_users()
        return web.json_response(dict(users=users))

主要

# main.py
from auth_service.api.role import RoleHandler
from auth_service.api.user import UsersCollectionView


def create_app(config, *, loop=None):
    loop = loop or asyncio.get_event_loop()

    app = Application()
    api_v1_app = Application()

    # Register all handlers
    role_handler = RoleHandler()
    role_handler.register(api_v1_app)
    api_v1_app.router.add_view('/users', UsersCollectionView)

    app.add_subapp('/api/v1', api_v1_app)
    app['api_v1'] = api_v1_app
    cors = aiohttp_cors.setup(app, defaults={
            "*": aiohttp_cors.ResourceOptions(
                allow_credentials=True,
                expose_headers="*",
                allow_methods="*",
                allow_headers="*",
                max_age=3600
            )
        })
        for route in app.router.routes():
            logger.info(f'Adding cors to {route.method} {route.handler}')
            cors.add(route)
    return app

if __name__ == '__main__':
    config = Config.from_environ()
    logger.info('Loaded config %r', config)
    app = create_app(config)
    run_app(app, port=config.server.port)

我尝试过的事情

  • 访问/api/v1/roles(协程处理程序)可以正常工作
  • 如果我删除CORS设置代码,则访问任何api路由都可以按预期工作
  • api_v1_app子应用程序实例上设置cors不能解决问题

我不知道如何进行故障排除。想知道一般情况下aiohttp-cors插件是否甚至可以支持这种情况,是否可以解决?

0 个答案:

没有答案