W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
在上一節(jié)中已經(jīng)對(duì)安全問(wèn)題進(jìn)行了描述,另外一個(gè)內(nèi)容是不能忽略的,那就是用戶登錄之后,對(duì)當(dāng)前用戶狀態(tài)(用戶是否登錄)進(jìn)行判斷。
用戶登錄之后,當(dāng)翻到別的目錄中時(shí),往往需要驗(yàn)證用戶是否處于登錄狀態(tài)。當(dāng)然,一種比較直接的方法,就是在轉(zhuǎn)到每個(gè)目錄時(shí),都從cookie中把用戶信息,然后傳到后端,跟數(shù)據(jù)庫(kù)驗(yàn)證。這不僅是直接的,也是基本的流程。但是,這個(gè)過(guò)程如果總讓用戶自己來(lái)做,框架的作用就顯不出來(lái)了。tornado就提供了一種用戶驗(yàn)證方法。
為了后面更工程化地使用tornado編程。需要將前面的已經(jīng)有的代碼進(jìn)行重新梳理。我只是將有修改的文件代碼寫出來(lái),不做過(guò)多解釋,必要的有注釋,相信讀者在前述學(xué)習(xí)基礎(chǔ)上,能夠理解。
在handler目錄中增加一個(gè)文件,名稱是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")
在這個(gè)文件中,目前只做一個(gè)事情,就是建立一個(gè)名為BaseHandler的類,然后在里面放置一個(gè)方法,就是得到當(dāng)前的cookie。在這里特別要向讀者說(shuō)明,在這個(gè)類中,其實(shí)還可以寫不少別的東西,比如你就可以將數(shù)據(jù)庫(kù)連接寫到這個(gè)類的初始化__init__()
方法中。因?yàn)樵谄渌念愔校覀円^承這個(gè)類。所以,這樣一個(gè)架勢(shì),就為讀者以后的擴(kuò)展增加了冗余空間。
然后把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) #將當(dāng)前用戶名寫入cookie,方法見(jiàn)下面
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): #增加了一個(gè)專門用來(lái)顯示錯(cuò)誤的頁(yè)面
def get(self): #但是后面不單獨(dú)講述,讀者可以從源碼中理解
self.render("error.html")
在index.py的類IndexHandler中,繼承了BaseHandler類,并且增加了一個(gè)方法set_current_user()用于將用戶名寫入cookie。請(qǐng)讀者特別注意那個(gè)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中把它讀出來(lái),使用user的值時(shí),還會(huì)用到:
tornado.escape.json_decode(value) Returns Python objects for the given JSON string
它們與json模塊中的dump()、load()功能相仿。
接下來(lái)要對(duì)user.py文件也進(jìn)行重寫:
#!/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
,這是一個(gè)裝飾器,它的作用就是完成tornado的認(rèn)證功能,即能夠得到當(dāng)前合法用戶。在原來(lái)的代碼中,用username = self.get_argument("user")
方法,從url中得到當(dāng)前用戶名,現(xiàn)在把它注釋掉,改用self.current_user
,這是和前面的裝飾器配合使用的,如果它的值為假,就根據(jù)setting中的設(shè)置,尋找login_url所指定的目錄(請(qǐng)關(guān)注下面對(duì)setting的配置)。
由于在index.py文件的set_current_user()方法中,是將user值轉(zhuǎn)化為json寫入cookie的,這里就得用username = tornado.escape.json_decode(self.current_user)
解碼。得到的username值,可以被用于后一句中的數(shù)據(jù)庫(kù)查詢。
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ù)這個(gè)設(shè)置,會(huì)返回到首頁(yè)。當(dāng)然,如果有單獨(dú)的登錄界面,比如是/login
,也可以login_url = '/login'
。
如此完成的是用戶登錄到網(wǎng)站之后,在頁(yè)面轉(zhuǎn)換的時(shí)候?qū)崿F(xiàn)用戶認(rèn)證。
為了演示本節(jié)的效果,我對(duì)教程的源碼進(jìn)行修改。讀者在閱讀的時(shí)候,可以參照源碼。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: