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")
相關文章
相關標籤/搜索