Tornado(cookie、XSRF、用户验证)

 
--------------------Cookie操做--------------------
一、设置Cookie
    一、set_cookie(name,value,domain=None,expires=None,path="/")
 
    二、参数说明:
        一、name:cookie名
        二、value:cookie值
        三、domain:提交cookie时匹配的域名
        四、path:提交cookie时匹配的路径
        五、expires:cookie的有效期,能够是时间戳整数、时间元组或者datetime类型,为UTC时间
        六、expires_days:cookie的有效期,天数,优先级低于expires
 
    三、实例:
        import datetime
 
        class IndexHandler(RequestHandler):
            def get(self):
                self.set_cookie("n1", "v1")
                self.set_cookie("n2", "v2", path="/new", expires=time.strptime("2016-11-11 23:59:59","%Y-%m-%d %H:%M:%S"))
                self.set_cookie("n3", "v3", expires_days=20)
                # 利用time.mktime将本地时间转换为UTC标准时间
                self.set_cookie("n4", "v4", expires=time.mktime(time.strptime("2016-11-11 23:59:59","%Y-%m-%d %H:%M:%S")))
                self.write("OK")
 
 
二、原理:
    一、设置cookie实际就是经过设置header的Set-Cookie来实现的。
 
    二、实例:
        class IndexHandler(RequestHandler):
            def get(self):
                self.set_header("Set-Cookie", "n5=v5; expires=Fri, 11 Nov 2016 15:59:59 GMT; Path=/")
                self.write("OK")
 
 
三、获取cookie
    一、get_cookie(name, default=None)
 
    二、参数说明:
        一、name:要获取的cookie的民称
 
        二、default:若是数据不存在,可设置默认值
 
    三、实例:
        class IndexHandler(RequestHandler):
            def get(self):
                n3 = self.get_cookie("n3")
                self.write(n3)
 
 
四、清楚cookie
    一、clear_cookie(name, path='/', domain=None):
        删除名为name,并同时匹配domain和path的cookie。
 
    二、clear_all_cookies(path='/', domain=None):
        删除同时匹配domain和path的全部cookie。
 
    三、实例:
        class ClearOneCookieHandler(RequestHandler):
            def get(self):
                self.clear_cookie("n3")
                self.write("OK")
 
        class ClearAllCookieHandler(RequestHandler):
            def get(self):
                self.clear_all_cookies()
                self.write("OK")
 
    四、注意:执行清除cookie操做后,并非当即删除了浏览器中的cookie,而是给cookie值置空,并改变其有效期使其失效。真正的删除cookie是由浏览器去清理的。
 
 
五、安全Cookie
    一、Cookie是存储在客户端浏览器中的,很容易被篡改。Tornado提供了一种对Cookie进行简易加密签名的方法来防止Cookie被恶意篡改。
 
    二、使用安全Cookie须要为应用配置一个用来给Cookie进行混淆的秘钥cookie_secret,将其传递给Application的构造函数。可使用以下方法来生成一个随机字符串做为cookie_secret的值:
        >ipython
        >import base64,uuid
        >base64.b64encode(uuid.uuid4().bytes + uuid.uuid4().bytes)
 
    三、将生成的cookie_secret传入Application的构造函数:
        app = tornado.web.Application(
            [(r"/", IndexHandler),],
            cookie_secret = "2hcicVu+TqShDpfsjMWQLZ0Mkq5NPEWSk9fi0zsSt3A="
        )
 
    四、set_secure_cookie(name, value, expires_days=30):
        设置一个带签名和时间戳的cookie,防止cookie被伪造。
 
    五、get_secure_cookie(name, value=None, max_age_days=31):
        若是cookie存在且验证经过,返回cookie的值,不然返回None。max_age_day不一样于expires_days,expires_days是设置浏览器中cookie的有效期,而max_age_day是过滤安全cookie的时间戳。
 
    六、实例:
        class IndexHandler(RequestHandler):
            def get(self):
                cookie = self.get_secure_cookie("count")
                count = int(cookie) + 1 if cookie else 1
                self.set_secure_cookie("count", str(count))
                self.write(
                    '<html><head><title>Cookie计数器</title></head>'
                    '<body><h1>您已访问本页%d次。</h1>' % count +
                    '</body></html>'
                )
 
 
--------------------XSRF保护--------------------
一、XSRF保护概念:
    一、浏览器有一个很重要的概念——同源策略(Same-Origin Policy)。所谓同源是指,域名,协议,端口相同。 不一样源的客户端脚本(javascript、ActionScript)在没明确受权的状况下,不能读写对方的资源。
 
    二、因为第三方站点没有访问cookie数据的权限(同源策略),因此能够要求每一个请求包括一个特定的参数值做为令牌来匹配存储在cookie中的对应值,若是二者匹配,的应用认定请求有效。而第三方站点没法在请求中包含令牌cookie值,这就有效地防止了不可信网站发送未受权的请求。
 
 
二、开启XSRF保护:
    一、要开启XSRF保护,须要在Application的构造函数中添加xsrf_cookies参数:
        app = tornado.web.Application(
            [(r"/", IndexHandler),],
            cookie_secret = "2hcicVu+TqShDpfsjMWQLZ0Mkq5NPEWSk9fi0zsSt3A=",
            xsrf_cookie = True
        )
 
    二、当这个参数被设置时,Tornado将拒绝请求参数中不包含正确的_xsrf值的POST、PUT和DELETE请求。用不带_xsrf的post请求时,报出了HTTP 403: Forbidden ('_xsrf' argument missing from POST)的错误。
 
    三、应用
        一、模板中应用
            在模板中添加:{% module xsrf_form_html() %}
 
        二、非模板中应用
            一、在任意的Handler中经过获取self.xsrf_token的值来生成_xsrf并设置Cookie:
                一、方法一:
                    class XSRFTokenHandler(RequestHandler):
                    """专门用来设置_xsrf Cookie的接口"""
                    def get(self):
                        self.xsrf_token
                        self.write("Ok")
 
                二、方法二:
                    class StaticFileHandler(tornado.web.StaticFileHandler):
                    """重写StaticFileHandler,构造时触发设置_xsrf Cookie"""
                    def __init__(self, *args, **kwargs):
                        super(StaticFileHandler, self).__init__(*args, **kwargs)
                        self.xsrf_token
 
        三、对于请求携带_xsrf参数,有两种方式:
            一、若请求体是表单编码格式的,能够在请求体中添加_xsrf参数
                //AJAX发送post请求,表单格式数据
                function xsrfPost() {
                    var xsrf = getCookie("_xsrf");
                    $.post("/new", "_xsrf="+xsrf+"&key1=value1", function(data) {
                        alert("OK");
                    });
                }
 
            二、若请求体是其余格式的(如json或xml等),能够经过设置HTTP头X-XSRFToken来传递_xsrf值
                $.ajax({
                    url: "/new",
                    method: "POST",
                    headers: {
                        "X-XSRFToken":xsrf,
                    },
                    data:json_data,
                    success:function(data) {
                        alert("OK");
                    }
                })
 
 
--------------------用户验证--------------------
一、概念:
    用户验证是指在收到用户请求后进行处理前先判断用户的认证状态(如登录状态),若经过验证则正常处理,不然强制用户跳转至认证页面(如登录页面)。
 
 
二、authenticated装饰器
    一、为了使用Tornado的认证功能,须要对登陆用户标记具体的处理函数。可使用@tornado.web.authenticated装饰器完成它。当使用这个装饰器包裹一个处理方法时,Tornado将确保这个方法的主体只有在合法的用户被发现时才会调用。
 
    二、实例:
        class ProfileHandler(RequestHandler):
            @tornado.web.authenticated
            def get(self):
                self.write("这是个人我的主页。")
 
 
三、get_current_user()方法
    一、装饰器@tornado.web.authenticated的判断执行依赖于请求处理类中的self.current_user属性,若是current_user值为假(None、False、0、""等),任何GET或HEAD请求都将把访客重定向到应用设置中login_url指定的URL,而非法用户的POST请求将返回一个带有403(Forbidden)状态的HTTP响应。
 
    二、在获取self.current_user属性的时候,tornado会调用get_current_user()方法来返回current_user的值。也就是说,验证用户的逻辑应写在get_current_user()方法中,若该方法返回非假值则验证经过,不然验证失败。
 
    三、实例:
        class ProfileHandler(RequestHandler):
            def get_current_user(self):
                """在此完成用户的认证逻辑"""
                user_name = self.get_argument("name", None)
                return user_name
 
            @tornado.web.authenticated
            def get(self):
                self.write("这是个人我的主页。")
 
 
四、login_url设置:
    一、当用户验证失败时,将用户重定向到login_url上,因此还须要在Application中配置login_url。
 
    二、实例:
        class LoginHandler(RequestHandler):
            def get(self):
                """在此返回登录页面"""
                self.write("登录页面")
 
        app = tornado.web.Application(
            [
                (r"/", IndexHandler),
                (r"/profile", ProfileHandler),
                (r"/login", LoginHandler),
            ],
            "login_url":"/login"
        )
 
    三、在login_url后面补充的next参数就是记录的跳转至登陆页面前的所在位置,因此可使用next参数来完成登录后的跳转。
        class LoginHandler(RequestHandler):
            def get(self):
                """登录处理,完成登录后跳转回前一页面"""
                next = self.get_argument("next", "/")
                self.redirect(next+"?name=logined")
相关文章
相关标签/搜索