Python:Tornado 第二章:實戰演練:開發Tornado網站:第八節:用戶身份認證

上一篇文章: Python:Tornado 第二章:實戰演練:開發Tornado網站:第七節:安全Cookie機制
下一篇文章: Python:Tornado 第二章:實戰演練:開發Tornado網站:第九節:防止跨站攻擊

在Tornado的RequestHandler類中有一個current_user屬性用於保存當前請求的用戶名。RequestHandler.get_current_user的默認值是None,在get()、post()等處理函數中能夠隨時讀取該屬性以獲取當前的用戶名。RequestHandler.current_user是一個只讀屬性,因此若是想要設置該屬性值,須要重載RequestHandler.get_current_user()函數以設置該屬性值。html

實例:使用RequestHandler.current_user屬性及RequestHandler.get_current_user()方法來實現用戶身份控制。

代碼:web

import tornado.web
import tornado.ioloop
import uuid  #UUID 生成庫

dict_sessions={}  #保存全部登陸的Session

class BaseHandler(tornado.web.RequestHandler):  #公共基類
    #寫入current_user的函數
    def get_current_user(self):
        session_id=self.get_secure_cookie("session_id")
        return dict_sessions.get(session_id)

class MainHandler(BaseHandler):
    @tornado.web.authenticated    #須要身份認證才能訪問的處理器
    def get(self):
        name=tornado.escape.xhtml_escape(self.current_user)
        self.write("Hello,"+name)

class LoginHandler(BaseHandler):
    def get(self):   #登錄頁面
        self.write('<html><>body'
                   '<form action="/login" method="post">'
                   'Name:<input type="text" name="name">'
                   '<input type="submit" value="Sign in">'
                   '</form></body></html>')
    def post(self):  #驗證是否運行登錄
        if len(self.get_argument("name"))<3:
            self.redirect("/login")
        session_id=str(uuid.uuid1())
        dict_sessions[session_id]=self.get_argument("name")
        self.set_secure_cookie("session_id",session_id)
        self.redirect("/")
setting={
    "cookie_secret":"SECRET_DONT_LEAK", #Cookie加密祕鑰
    "login_url":"/login"  #定義登錄頁面
}
application=tornado.web.Application([
    (r"/",MainHandler),        #URL映射定義
    (r"/login",LoginHandler)
],**setting)

def main():
    application.listen(8888)
    tornado.ioloop.IOLoop.current().start()     #掛起監聽

if __name__ == '__main__':
    main()

本例演示了一個完整的身份認證編程框架,總體構思以下:數據庫

  • 用全局字典dict_sessions保存已經登陸的用戶信息,爲了簡單些,本例只保存了【回話ID:用戶名】的鍵值對。
  • 定義公共基類BaseHandler,該類繼承自tornado.web.RequestHandler,用於定義本網站全部處理器的公共屬性和行爲。重載它的get_current_user()函數,其在訪問RequestHandler.current_user屬性時自動被Tornado調用。該函數首先用get_secure_cookie()得到本次訪問的回話ID,而後利用該ID從dict_sessions中得到用戶名而且返回。
  • MainHandler類是一個要求用戶通過身份認證才能訪問的處理器實例。該處理器中的處理函數get()使用了裝飾器tornado.web.authenticated,具備該裝飾器的處理函數在執行以前根據current_user是否已經被賦值來判斷用戶的身份認證狀況,若是已經被賦值則能夠進行正常邏輯,不然自動重定向到網站的登陸頁面。
  • LoginHandler類是登陸頁面處理器,其get()函數用於渲染登陸頁面,post()函數用於驗證是否容許用戶登錄。
  • 在tornado.web.Application的初始化函數中經過login_url參數給出網站的登錄頁面地址。該地址被用於tornado.web.authenticated裝飾器在發現用戶還沒有驗證時重定向到一個URL。
注意:加入身份認證的全部頁面處理器須要繼承自BaseHandler類,而不是直接繼承原來的tornado.web.RequestHandler類。

商用的身份認證還要完善更多的內容,好比加入密碼驗證機制、管理登錄超時、將用戶信息保存到數據庫等。編程

相關文章
相關標籤/搜索