使用异步回调的cookie密钥认证 [英] Authentication using cookie key with asynchronous callback

查看:276
本文介绍了使用异步回调的cookie密钥认证的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要编写与远程验证API异步回调认证功能。用简单的登录认证工作良好,但与饼干密钥授权,不能正常工作。它应该检查是否在饼干present键lp_login,取API URL像异步和执行on_response功能。

在code差不多的作品,但我看到两个问题。首先,在on_response的功能,我需要设置的每一页上的授权用户安全cookie。在code USER_ID返回正确的ID,但行:self.set_secure_cookie(用户,USER_ID)开不工作。为什么会这样?

和第二个问题。在异步获取API URL,用户的页面已经on_response设置cookie的使用键用户页面会与链接未授权的部分,登录或之前加载。这将是用户感到困惑。为了解决这个问题,我可以为用户谁试图加载网站的第一页停止加载页面。是否有可能做的,怎么样?也许问题已经解决它更正确的方式?

 类BaseHandler(tornado.web.RequestHandler):
    @ tornado.web.asynchronous
    高清get_current_user(个体经营):
        USER_ID = self.get_secure_cookie(用户)
        user_cookie = self.get_cookie(lp_login)
        如果USER_ID:
            self.set_secure_cookie(用户,USER_ID)
            返回Author.objects.get(ID = INT(USER_ID))
        ELIF user_cookie:
            URL =里urlparse(HTTP://%的%self.request.host)
            域= url.netloc.split(:)[0]
            尝试:
                用户名,hashed_pa​​ssword = urllib.unquote(user_cookie).rsplit(,,1)
            除了ValueError错误:
                针对恶意客户端#检查
                返回None
            其他:
                URL =HTTP://%s%S%S /%S /%(域,/ API /用户/用户名/,用户名,hashed_pa​​ssword)
                HTTP = tornado.httpclient.AsyncHTTPClient()
                http.fetch(URL,回调= self.async_callback(self.on_response))
        其他:
            返回None    高清on_response(个体经营,响应):
        答案= tornado.escape.json_de code(response.body)
        用户名=答案[用户名]
        如果答案[has_valid_credentials]:
            笔者= Author.objects.get(电子邮件=答案[电子邮件])
            USER_ID = STR(author.id)
            打印USER_ID#它返回所需的ID
            self.set_secure_cookie(用户,USER_ID)#但是会话的设置


解决方案

看来你跨张贴这龙卷风邮件列表的这里

一个你正在运行到的问题是,你无法启动 get_current_user 里面的异步调用,您只能启动从发生的事情里面的异步调用的 GET

我没有测试过,但我认为这应该让你接近你所期待的。

 #!/ bin中/蟒蛇
进口tornado.web
进口tornado.http
进口tornado.escape
进口functools
进口记录
进口的urllib进口作者高清upgrade_lp_login_cookie(方法):
    @ functools.wraps(法)
    高清封装(个体经营,* ARGS,** kwargs):
        如果不是self.current_user和self.get_cookie('lp_login'):
            self.upgrade_lp_login(self.async_callback(方法,自我,* ARGS,** kwargs))
        其他:
            返回方法(个体经营,* ARGS,** kwargs)
    包装回报
类BaseHandler(tornado.web.RequestHandler):
    高清get_current_user(个体经营):
        USER_ID = self.get_secure_cookie(用户)
        如果USER_ID:
            返回Author.objects.get(ID = INT(USER_ID))    高清upgrade_lp_login(个体经营,回调):
        lp_login = self.get_cookie(lp_login)
        尝试:
            用户名,hashed_pa​​ssword = urllib.unquote(lp_login).rsplit(,,1)
        除了ValueError错误:
            针对恶意客户端#检查
            logging.info('无效lp_login饼干%s'的%lp_login)
            返回回调()        URL =HTTP://%(主机)S / API /用户/用户名/%S /%S%(self.request.host,
                                                        urllib.quote(用户名)
                                                        urllib.quote(hashed_pa​​ssword))
        HTTP = tornado.httpclient.AsyncHTTPClient()
        http.fetch(URL,self.async_callback(self.finish_upgrade_lp_login,回调))    高清finish_upgrade_lp_login(个体经营,回调,响应):
        答案= tornado.escape.json_de code(response.body)
        #用户名=答案[用户名]
        如果答案['has_valid_credentials']:
            #设置self.current_user,覆盖self.get_current_user的previous输出()
            self._current_user = Author.objects.get(电子邮件=答案[电子邮件])
            #设置下一个请求饼干
            self.set_secure_cookie(用户,STR(self.current_user.id))        #现在链中真正的GET / POST方法
        回电话()    @upgrade_lp_login_cookie
    DEF得到(个体经营):
        self.render('template.tmpl')

I need to write authentication function with asynchronous callback from remote Auth API. Simple authentication with login is working well, but authorization with cookie key, does not work. It should checks if in cookies present key "lp_login", fetch API url like async and execute on_response function.

The code almost works, but I see two problems. First, in on_response function I need to setup secure cookie for authorized user on every page. In code user_id returns correct ID, but line: self.set_secure_cookie("user", user_id) does't work. Why it can be?

And second problem. During async fetch API url, user's page has loaded before on_response setup cookie with key "user" and the page will has an unauthorized section with link to login or sign on. It will be confusing for users. To solve it, I can stop loading page for user who trying to load first page of site. Is it possible to do and how? Maybe the problem has more correct way to solve it?

class BaseHandler(tornado.web.RequestHandler):
    @tornado.web.asynchronous
    def get_current_user(self):
        user_id = self.get_secure_cookie("user")
        user_cookie = self.get_cookie("lp_login")
        if user_id:
            self.set_secure_cookie("user", user_id)
            return Author.objects.get(id=int(user_id))
        elif user_cookie:
            url = urlparse("http://%s" % self.request.host)
            domain = url.netloc.split(":")[0]
            try:
                username, hashed_password = urllib.unquote(user_cookie).rsplit(',',1)
            except ValueError:
                # check against malicious clients
                return None
            else:
                url = "http://%s%s%s/%s/" % (domain, "/api/user/username/", username, hashed_password)
                http = tornado.httpclient.AsyncHTTPClient()
                http.fetch(url, callback=self.async_callback(self.on_response))
        else:
            return None

    def on_response(self, response):
        answer = tornado.escape.json_decode(response.body)
        username = answer['username']
        if answer["has_valid_credentials"]:
            author = Author.objects.get(email=answer["email"])
            user_id = str(author.id)
            print user_id # It returns needed id
            self.set_secure_cookie("user", user_id) # but session can's setup

解决方案

It seems you cross-posted this on the tornado mailing list here

One of the problems you are running into is that you can't start the async call inside of get_current_user, you can only start an async call from something that happens inside of get or post.

I've not tested it, but i think this should get you close to what you are looking for.

#!/bin/python
import tornado.web
import tornado.http
import tornado.escape
import functools
import logging
import urllib

import Author

def upgrade_lp_login_cookie(method):
    @functools.wraps(method)
    def wrapper(self, *args, **kwargs):
        if not self.current_user and self.get_cookie('lp_login'):
            self.upgrade_lp_login(self.async_callback(method, self, *args, **kwargs))
        else:
            return method(self, *args, **kwargs)
    return wrapper


class BaseHandler(tornado.web.RequestHandler):
    def get_current_user(self):
        user_id = self.get_secure_cookie("user")
        if user_id:
            return Author.objects.get(id=int(user_id))

    def upgrade_lp_login(self, callback):
        lp_login = self.get_cookie("lp_login")
        try:
            username, hashed_password = urllib.unquote(lp_login).rsplit(',',1)
        except ValueError:
            # check against malicious clients
            logging.info('invalid lp_login cookie %s' % lp_login)
            return callback()

        url = "http://%(host)s/api/user/username/%s/%s" % (self.request.host, 
                                                        urllib.quote(username), 
                                                        urllib.quote(hashed_password))
        http = tornado.httpclient.AsyncHTTPClient()
        http.fetch(url, self.async_callback(self.finish_upgrade_lp_login, callback))

    def finish_upgrade_lp_login(self, callback, response):
        answer = tornado.escape.json_decode(response.body)
        # username = answer['username']
        if answer['has_valid_credentials']:
            # set for self.current_user, overriding previous output of self.get_current_user()
            self._current_user = Author.objects.get(email=answer["email"])
            # set the cookie for next request
            self.set_secure_cookie("user", str(self.current_user.id))

        # now chain to the real get/post method
        callback()

    @upgrade_lp_login_cookie
    def get(self):
        self.render('template.tmpl')

这篇关于使用异步回调的cookie密钥认证的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆