W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
在上一節(jié)中已經(jīng)對安全問題進行了描述,另外一個內(nèi)容是不能忽略的,那就是用戶登錄之后,對當前用戶狀態(tài)(用戶是否登錄)進行判斷。
用戶登錄之后,當翻到別的目錄中時,往往需要驗證用戶是否處于登錄狀態(tài)。當然,一種比較直接的方法,就是在轉(zhuǎn)到每個目錄時,都從cookie中把用戶信息,然后傳到后端,跟數(shù)據(jù)庫驗證。這不僅是直接的,也是基本的流程。但是,這個過程如果總讓用戶自己來做,框架的作用就顯不出來了。tornado就提供了一種用戶驗證方法。
為了后面更工程化地使用tornado編程。需要將前面的已經(jīng)有的代碼進行重新梳理。我只是將有修改的文件代碼寫出來,不做過多解釋,必要的有注釋,相信讀者在前述學(xué)習(xí)基礎(chǔ)上,能夠理解。
在handler目錄中增加一個文件,名稱是base.py,代碼如下:
#! /usr/bin/env python
# coding=utf-8
import tornado.web
class BaseHandler(tornado.web.RequestHandler):
def get_current_user(self):
return self.get_secure_cookie("user")
在這個文件中,目前只做一個事情,就是建立一個名為BaseHandler的類,然后在里面放置一個方法,就是得到當前的cookie。在這里特別要向讀者說明,在這個類中,其實還可以寫不少別的東西,比如你就可以將數(shù)據(jù)庫連接寫到這個類的初始化__init__()
方法中。因為在其它的類中,我們要繼承這個類。所以,這樣一個架勢,就為讀者以后的擴展增加了冗余空間。
然后把index.py文件改寫為:
#!/usr/bin/env python
# coding=utf-8
import tornado.escape
import methods.readdb as mrd
from base import BaseHandler
class IndexHandler(BaseHandler): #繼承base.py中的類BaseHandler
def get(self):
usernames = mrd.select_columns(table="users",column="username")
one_user = usernames[0][0]
self.render("index.html", user=one_user)
def post(self):
username = self.get_argument("username")
password = self.get_argument("password")
user_infos = mrd.select_table(table="users",column="*",condition="username",value=username)
if user_infos:
db_pwd = user_infos[0][2]
if db_pwd == password:
self.set_current_user(username) #將當前用戶名寫入cookie,方法見下面
self.write(username)
else:
self.write("-1")
else:
self.write("-1")
def set_current_user(self, user):
if user:
self.set_secure_cookie('user', tornado.escape.json_encode(user)) #注意這里使用了tornado.escape.json_encode()方法
else:
self.clear_cookie("user")
class ErrorHandler(BaseHandler): #增加了一個專門用來顯示錯誤的頁面
def get(self): #但是后面不單獨講述,讀者可以從源碼中理解
self.render("error.html")
在index.py的類IndexHandler中,繼承了BaseHandler類,并且增加了一個方法set_current_user()用于將用戶名寫入cookie。請讀者特別注意那個tornado.escape.json_encode()方法,其功能是:
tornado.escape.json_encode(value) JSON-encodes the given Python object.
如果要查看源碼,可以閱讀:http://www.tornadoweb.org/en/branch2.3/escape.html
這樣做的本質(zhì)是把user轉(zhuǎn)化為json,寫入到了cookie中。如果從cookie中把它讀出來,使用user的值時,還會用到:
tornado.escape.json_decode(value) Returns Python objects for the given JSON string
它們與json模塊中的dump()、load()功能相仿。
接下來要對user.py文件也進行重寫:
#!/usr/bin/env python
# coding=utf-8
import tornado.web
import tornado.escape
import methods.readdb as mrd
from base import BaseHandler
class UserHandler(BaseHandler):
@tornado.web.authenticated
def get(self):
#username = self.get_argument("user")
username = tornado.escape.json_decode(self.current_user)
user_infos = mrd.select_table(table="users",column="*",condition="username",value=username)
self.render("user.html", users = user_infos)
在get()方法前面添加@tornado.web.authenticated
,這是一個裝飾器,它的作用就是完成tornado的認證功能,即能夠得到當前合法用戶。在原來的代碼中,用username = self.get_argument("user")
方法,從url中得到當前用戶名,現(xiàn)在把它注釋掉,改用self.current_user
,這是和前面的裝飾器配合使用的,如果它的值為假,就根據(jù)setting中的設(shè)置,尋找login_url所指定的目錄(請關(guān)注下面對setting的配置)。
由于在index.py文件的set_current_user()方法中,是將user值轉(zhuǎn)化為json寫入cookie的,這里就得用username = tornado.escape.json_decode(self.current_user)
解碼。得到的username值,可以被用于后一句中的數(shù)據(jù)庫查詢。
application.py中的setting也要做相應(yīng)修改:
#!/usr/bin/env python
# coding=utf-8
from url import url
import tornado.web
import os
setting = dict(
template_path = os.path.join(os.path.dirname(__file__), "templates"),
static_path = os.path.join(os.path.dirname(__file__), "statics"),
cookie_secret = "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=",
xsrf_cookies = True,
login_url = '/',
)
application = tornado.web.Application(
handlers = url,
**setting
)
與以前代碼的重要區(qū)別在于login_url = '/',
,如果用戶不合法,根據(jù)這個設(shè)置,會返回到首頁。當然,如果有單獨的登錄界面,比如是/login
,也可以login_url = '/login'
。
如此完成的是用戶登錄到網(wǎng)站之后,在頁面轉(zhuǎn)換的時候?qū)崿F(xiàn)用戶認證。
為了演示本節(jié)的效果,我對教程的源碼進行修改。讀者在閱讀的時候,可以參照源碼。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: