用tornado做網(wǎng)站(6)

2018-02-24 15:48 更新

上一節(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é)的效果,我對教程的源碼進行修改。讀者在閱讀的時候,可以參照源碼。

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號