Асинхронное промежуточное ПО в торнадо - PullRequest
0 голосов
/ 26 декабря 2018

Моя цель - проверить токен доступа перед каждой инициализацией запроса веб-сокета.Для этого мне нужно позвонить на мой oauth-сервер.Поэтому попытался добавить промежуточное программное обеспечение, которое будет проверять токен доступа.Я нашел, как добавить промежуточное ПО по этой ссылке https://github.com/tornadoweb/tornado/issues/49, которая работает нормально.Но проблема в том, что когда я звоню на свой oauth-сервер, я делаю это асинхронно, и кажется, что промежуточное ПО не может быть асинхронным.Вот мой пример кода

app = Application()


async def middleware(request):
    userToken = request.headers.get('Authorization')
    active = await check_accesstoken(userToken)
    if not active:
      return error
    app(request)

async def check_accesstoken(userToken):
    http_client = httpclient.AsyncHTTPClient()
    post_data = {'token': userToken, 'scope': 'email phone'}
    api_endpoint = 'https://192.168.0.4:1445/oauth2/introspect'
    json_data = json.dumps(post_data)

    response = await http_client.fetch(api_endpoint,
                                       raise_error=False,
                                       method='POST',
                                       body=json_data
                                       # headers=headers
                                       )
    return response.body.active:


def main():    
    http_server = tornado.httpserver.HTTPServer(middleware)
    http_server.listen(PORT, HOST) 
    tornado.ioloop.IOLoop.current().start()

if __name__ == '__main__':
    main()

Получение следующей ошибки.

RuntimeWarning: сопрограмма 'middleware' никогда не ожидалась
self.request_callback (self.request)

Вопросы

  1. Как добавить промежуточное программное обеспечение aync?

  2. Или я должен сделать синхронный вызов на oauth-сервер?

  3. Или есть другое место, где я должен проверить токен доступа?

1 Ответ

0 голосов
/ 26 декабря 2018

Да, это больше проблем, чем стоит переопределить HTTPServer.

Более разумное решение, которое приходит на ум - вы можете создать подкласс RequestHandler и создать prepare()метод на том подклассе, где вы можете проверить токен доступа.

Затем создайте все ваши обработчики из этого подкласса.Вот пример:

class BaseHandler(web.RequestHandler):
    async def prepare(self):
        active = await check_accesstoken(userToken)
        if not active:
            self.write("Error")
            self.finish()


class SomeHandler(BaseHandler):
    ...

И если вам нужно также создать метод prepare() для ваших обработчиков, просто вызовите BaseHandler s prepare, используя super().

...