Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Tornado-从等待中获取返回值(多个回调)_Python_Async Await_Tornado - Fatal编程技术网

Python Tornado-从等待中获取返回值(多个回调)

Python Tornado-从等待中获取返回值(多个回调),python,async-await,tornado,Python,Async Await,Tornado,我正在tornado中使用OAuth2身份验证开发一个应用程序。登录类如下所示: class IDPLogin(tornado.web.RequestHandler, IDPLoginHandler): async def get(self): if self.get_argument('code', False): access = await self.get_authenticated_user( ...

我正在tornado中使用OAuth2身份验证开发一个应用程序。登录类如下所示:

class IDPLogin(tornado.web.RequestHandler, IDPLoginHandler):
    async def get(self):
        if self.get_argument('code', False):
            access = await self.get_authenticated_user(
                ...
            )
            print(type(access))
            #self.set_secure_cookie('user', self.get_argument('code'))
            #self.redirect('/')
        else:
            await self.authorize_redirect(
                ...
            )
class IDPLoginHandler(tornado.auth.OAuth2Mixin):
...
    async def get_authenticated_user(self, redirect_uri, client_id, client_secret, code):
        #do fetching and return future result
    async def get_user_info(self, access_token):
        #do fetching and return future result
使用get_authenticated_user方法,查看以下两个额外回调,以获取评估用户所需的所有详细信息:

class IDPHubLoginHandler(tornado.auth.OAuth2Mixin):
    def __init__(self):
        self._OAUTH_AUTHORIZE_URL = "..."
        self._OAUTH_ACCESS_TOKEN_URL = "..."
        self._USERINFO_ENDPOINT = "..."

    async def get_authenticated_user(self, redirect_uri, client_id, client_secret, code):
        http = self.get_auth_http_client()
        body = urllib_parse.urlencode({
            "redirect_uri": redirect_uri,
            "code": code,
            "client_id": client_id,
            "client_secret": client_secret,
            "grant_type": "authorization_code",
        })
        fut = http.fetch(self._OAUTH_ACCESS_TOKEN_URL,
                         method="POST",
                         headers={'Content-Type': 'application/x-www-form-urlencoded'},
                         body=body)
        fut.add_done_callback(wrap(functools.partial(self._on_access_token)))

    def _on_access_token(self, future):
        """Callback function for the exchange to the access token."""
        try:
            response = future.result()
        except Exception as e:
            future.set_exception(AuthError('IDP auth error: %s' % str(e)))
            return

        args = escape.json_decode(response.body)
        # Fetch userinfo
        http = self.get_auth_http_client()
        fut = http.fetch(self._USERINFO_ENDPOINT,
                         method="GET",
                         headers={
                             'Authorization': 'Bearer ' + args['access_token'],
                             'accept': 'application/json'
                         }
        )
        fut.add_done_callback(wrap(functools.partial(self._on_userinfo)))

    def _on_userinfo(self, future):
        response = future.result()
        r_body = escape.json_decode(response.body)
        return r_body
我希望能够访问在_on_userinfo回调中返回的主体,但登录类中的访问权限为“NoneType”,我希望评估响应,以便拒绝访问或向用户提供cookie

给出的代码成功地获得了所有必需的输入数据,但我很难理解如何从回调返回值,并在主登录类IDPLogin中重用它们。我查阅了龙卷风的文档,没有找到答案。Oauth2/OpenID示例充其量在细节上非常简短


尝试在asyncio.base\u futures.InvalidStateError中设置未来结果的结果。

找到了另一种方法。不确定这是否是最规范的方式,但似乎能完成任务

按如下方式实现Oauth2 Mixin:

class IDPLogin(tornado.web.RequestHandler, IDPLoginHandler):
    async def get(self):
        if self.get_argument('code', False):
            access = await self.get_authenticated_user(
                ...
            )
            print(type(access))
            #self.set_secure_cookie('user', self.get_argument('code'))
            #self.redirect('/')
        else:
            await self.authorize_redirect(
                ...
            )
class IDPLoginHandler(tornado.auth.OAuth2Mixin):
...
    async def get_authenticated_user(self, redirect_uri, client_id, client_secret, code):
        #do fetching and return future result
    async def get_user_info(self, access_token):
        #do fetching and return future result
使用主登录处理程序中的等待关键字顺序调用方法:

class IDPLogin(tornado.web.RequestHandler, IDPLoginHandler):
    async def get(self):
        if self.get_argument('code', False):
            response_token = await self.get_authenticated_user(
                ...
            )
            token = escape.json_decode(response_token.body)['access_token']
            response_userinfo = await self.get_user_info(token)

是的,这是正确的方法。如果您使用的是异步/等待语法,则不需要回调。