在龙卷风中获取当前用户异步
Get current user Async in Tornado
当我使用 get_current_user() 时,我需要检查 Redis 中的一些东西(使用 tornado-redis) 异步。
我正在做以下事情:
def authenticated_async(method):
@gen.coroutine
def wrapper(self, *args, **kwargs):
self._auto_finish = False
self.current_user = yield gen.Task(self.get_current_user_async)
if not self.current_user:
self.redirect(self.reverse_url('login'))
else:
result = method(self, *args, **kwargs) # updates
if result is not None:
yield result
return wrapper
class BaseClass():
@gen.coroutine
def get_current_user_async(self,):
auth_cookie = self.get_secure_cookie('user') # cfae7a25-2b8b-46a6-b5c4-0083a114c40e
user_id = yield gen.Task(c.hget, 'auths', auth_cookie) # 16
print(123, user_id)
return auth_cookie if auth_cookie else None
比如我要使用authenticated_async装饰器:
class IndexPageHandler(BaseClass, RequestHandler):
@authenticated_async
def get(self):
self.render("index.html")
但我只有控制台123.
怎么了?如何解决?
谢谢!
更新
我已经用 yield result
更新了代码。
在auth_cookie我有cfae7a25-2b8b-46a6-b5c4-0083a114c40e
.
然后我去终端:
127.0.0.1:6379> hget auths cfae7a25-2b8b-46a6-b5c4-0083a114c40e
"16"
所以,
user_id = yield gen.Task(c.hget, 'auths', auth_cookie)
print(123, user_id)
必须return
123 16
但它 return 是一个 123
更新 1
有
class IndexPageHandler(BaseClass, RequestHandler):
@gen.coroutine
def get(self):
print('cookie', self.get_secure_cookie('user'))
user_async = yield self.get_current_user_async()
print('user_async', user_async)
print('current user', self.current_user)
self.render("index.html",)
在控制台我有:
cookie b'cfae7a25-2b8b-46a6-b5c4-0083a114c40e'
123
user_async b'cfae7a25-2b8b-46a6-b5c4-0083a114c40e'
current user None
查看 gen.Task 的文档字符串:
Takes a function (and optional additional arguments) and runs it with
those arguments plus a callback
keyword argument.
c.hget是否接受回调参数?如果没有,回调将抛出异常,未来不会设置结果,因此打印语句不会打印用户标识。
get_secure_cookie()
returns一个字节串;由于打印出带有 b'
前缀的 cookie,因此您必须在 Python 3 上。在 Python 3 上,tornado-redis
似乎需要 unicode 字符串而不是字节字符串;任何不是 unicode 字符串的输入都将使用 str()
函数转换为一个。这会添加上面看到的 b'
前缀,因此您查询的是 b'cfae7a25-2b8b-46a6-b5c4-0083a114c40e'
,而不是 cfae7a25-2b8b-46a6-b5c4-0083a114c40e
解决办法是先把cookie转成str
再发送到redis:auth_cookie = tornado.escape.native_str(auth_cookie)
答案在您的包装协程中。
if result is not None:
yield result
您不想产生结果,而是要 "return" 它来自协程。但是,由于 Python 不允许您使用生成器中的非空 return,因此您需要将其作为 Tornado 可以解包的包装异常提出,并将结果传递给调用者( get_current_user)
if result is not None:
raise gen.Return(result)
完成后,您应该会发现它有效。
当我使用 get_current_user() 时,我需要检查 Redis 中的一些东西(使用 tornado-redis) 异步。
我正在做以下事情:
def authenticated_async(method):
@gen.coroutine
def wrapper(self, *args, **kwargs):
self._auto_finish = False
self.current_user = yield gen.Task(self.get_current_user_async)
if not self.current_user:
self.redirect(self.reverse_url('login'))
else:
result = method(self, *args, **kwargs) # updates
if result is not None:
yield result
return wrapper
class BaseClass():
@gen.coroutine
def get_current_user_async(self,):
auth_cookie = self.get_secure_cookie('user') # cfae7a25-2b8b-46a6-b5c4-0083a114c40e
user_id = yield gen.Task(c.hget, 'auths', auth_cookie) # 16
print(123, user_id)
return auth_cookie if auth_cookie else None
比如我要使用authenticated_async装饰器:
class IndexPageHandler(BaseClass, RequestHandler):
@authenticated_async
def get(self):
self.render("index.html")
但我只有控制台123.
怎么了?如何解决?
谢谢!
更新
我已经用 yield result
更新了代码。
在auth_cookie我有cfae7a25-2b8b-46a6-b5c4-0083a114c40e
.
然后我去终端:
127.0.0.1:6379> hget auths cfae7a25-2b8b-46a6-b5c4-0083a114c40e
"16"
所以,
user_id = yield gen.Task(c.hget, 'auths', auth_cookie)
print(123, user_id)
必须return
123 16
但它 return 是一个 123
更新 1
有
class IndexPageHandler(BaseClass, RequestHandler):
@gen.coroutine
def get(self):
print('cookie', self.get_secure_cookie('user'))
user_async = yield self.get_current_user_async()
print('user_async', user_async)
print('current user', self.current_user)
self.render("index.html",)
在控制台我有:
cookie b'cfae7a25-2b8b-46a6-b5c4-0083a114c40e'
123
user_async b'cfae7a25-2b8b-46a6-b5c4-0083a114c40e'
current user None
查看 gen.Task 的文档字符串:
Takes a function (and optional additional arguments) and runs it with those arguments plus a
callback
keyword argument.
c.hget是否接受回调参数?如果没有,回调将抛出异常,未来不会设置结果,因此打印语句不会打印用户标识。
get_secure_cookie()
returns一个字节串;由于打印出带有 b'
前缀的 cookie,因此您必须在 Python 3 上。在 Python 3 上,tornado-redis
似乎需要 unicode 字符串而不是字节字符串;任何不是 unicode 字符串的输入都将使用 str()
函数转换为一个。这会添加上面看到的 b'
前缀,因此您查询的是 b'cfae7a25-2b8b-46a6-b5c4-0083a114c40e'
,而不是 cfae7a25-2b8b-46a6-b5c4-0083a114c40e
解决办法是先把cookie转成str
再发送到redis:auth_cookie = tornado.escape.native_str(auth_cookie)
答案在您的包装协程中。
if result is not None:
yield result
您不想产生结果,而是要 "return" 它来自协程。但是,由于 Python 不允许您使用生成器中的非空 return,因此您需要将其作为 Tornado 可以解包的包装异常提出,并将结果传递给调用者( get_current_user)
if result is not None:
raise gen.Return(result)
完成后,您应该会发现它有效。