1. 程式人生 > >2Python全棧之路系列之Tornado的Cookie與Sess

2Python全棧之路系列之Tornado的Cookie與Sess

request

Python全棧之路系列之Tornado的Cookie與Sess


主要的代碼結構為:

#!/usr/bin/env python
# _*_coding:utf-8 _*_

import tornado.ioloop
import tornado.web

class MainHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        """
        這裏的代碼將操作cookie與session
        """
        self.write(‘Hello World‘)
        
application = tornado.web.Application([
    (r‘/‘, MainHandler),
])

if __name__ == "__main__":
    print(‘http://127.0.0.1:8888/‘)
    application.listen(8888)
    tornado.ioloop.IOLoop.instance().start()

COokie是保存在瀏覽器的一個鍵值對,每次的HTTP請求都會攜帶Cookie

獲取所有的Cookies

self.cookies

設置Cookie

self.set_cookie(self, name, value, domain=None, expires=None, path="/", expires_days=None, **kwargs)

可接受的參數描述:

參數描述
nameCookie的Key
valueCookie的value
domain生效的域名
expires以秒為過期時間,默認從1970-01-01T00:00:10.000Z
path生效路徑
expires_days以天數過期時間,如果設置為None
則關閉瀏覽器Cookie就失效

設置cookie過期時間為15分鐘以後的代碼為:

self.set_cookie(‘key‘, ‘value‘, expires=time.time()+900)

MainHandler的代碼

class MainHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        # 獲取cookie,如果沒有獲取到,值就是None
        if self.get_cookie(‘key‘, None) == None:
            # 設置一個cookie
            self.set_cookie(‘key‘, ‘val‘)
            STRING = ‘Hello World‘
        else:
            # 獲取cookie的值賦給STRING
            STRING = self.get_cookie(‘key‘)
        # 如果沒有獲取到Cookie則輸出‘Hello World‘,否則就輸出Cookie的值
        self.write(STRING)

要使用加密的Cookie,你需要在創建應用時提供一個密鑰,名字為cookie_secret, 你可以把它作為一個關鍵詞參數傳入應用的設置中:

application = tornado.web.Application([
    (r‘/‘, MainHandler),
], cookie_secret="508CE6152CB93994628D3E99934B83CC")

設置一個加密Cookie所需要的參數

self.set_secure_cookie(self, name, value, expires_days=30, version=None, **kwargs):

參數和上面的大同小異。

MainHandler的代碼

class MainHandler(tornado.web.RequestHandler):
    def get(self, *args, **kwargs):
        # 獲取cookie,如果沒有獲取到,值就是None
        if self.get_secure_cookie(‘key‘, None) == None:
            # 設置一個cookie
            self.set_secure_cookie(‘key‘, ‘val‘)
            STRING = ‘Hello World‘
        else:
            # 獲取cookie的值賦給STRING
            STRING = self.get_secure_cookie(‘key‘)
        # 如果沒有獲取到Cookie則輸出‘Hello World‘,否則就輸出Cookie的值
        self.write(STRING)

寫cookie過程:

  1. 將值進行base64加密

  2. 對除值以外的內容進行簽名,哈希算法(無法逆向解析)

  3. 拼接 簽名 + 加密值

讀cookie過程:

  1. 讀取簽名 + 加密值

  2. 對簽名進行驗證

  3. base64解密,獲取值內容

# app01.py
#!/usr/bin/env python
# _*_ coding: utf-8 _*_

import tornado.web
import tornado.ioloop

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        self.set_secure_cookie(‘username‘, ‘ansheng‘)
        self.set_secure_cookie(‘password‘, ‘hello‘)
        self.render(‘index.html‘)
        
    def post(self, *args, **kwargs):
        username = self.get_argument(‘username‘, None)
        password = self.get_argument(‘password‘, None)
        cooike_user = str(self.get_secure_cookie(‘username‘), encoding=‘utf-8‘)
        cooike_pass = str(self.get_secure_cookie(‘password‘), encoding=‘utf-8‘)
        if username == cooike_user and password == cooike_pass:
            self.write(‘Hello ‘ + cooike_user)
        else:
            self.write(‘用戶名或密碼錯誤‘)
            
settings = {
    ‘template_path‘: ‘template‘,
}

application = tornado.web.Application([
    (r‘/‘, IndexHandler),
], **settings,
    cookie_secret="508CE6152CB93994628D3E99934B83CC")
    
if __name__ == ‘__main__‘:
    print(‘http://127.0.0.1:8000‘)
    application.listen(8000)
    tornado.ioloop.IOLoop.instance().start()

HTML文件內容

<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body>

<form method="post" action="/">
    <input type="text" name="username" />
    <input type="text" name="password" />
    <input type="submit" value="提交" />
</form>

</body>
</html>

演示結果如下:
技術分享

Session

Tornado中是不提供像Cookie這種直接設置Session的,需要我們自己寫插件來進行對Session的增刪改

Session的數據是保存在服務端的,如果要應用Session必須要依賴Cookie,因為Cookie的值就等於Session的Key

Session在內存中的存儲方式如下:

key(隨機字符串) = {
    {‘k1‘,‘v1‘},
    {‘k2‘,‘v2‘},
    {‘k3‘,‘v3‘},
    ....
}

key(隨機字符串) = {
    {‘k1‘,‘v1‘},
    {‘k2‘,‘v2‘},
    {‘k3‘,‘v3‘},
    ....
}

key(隨機字符串) = {
    {‘k1‘,‘v1‘},
    {‘k2‘,‘v2‘},
    {‘k3‘,‘v3‘},
    ....
}
.....

一個設置與獲取Session的小腳本:

#!/usr/bin/env python
# _*_ coding: utf-8 _*_

import tornado.web
import tornado.ioloop

container = {}

class Session:
    def __init__(self, Handler):
        self.Handler = Handler
        self.random_str = None
        
    # 隨機字符串
    def __genarate_random_str(self):
        import hashlib
        import time
        obj = hashlib.md5()
        obj.update(bytes(str(time.time()), encoding=‘utf-8‘))
        random_str = obj.hexdigest()
        return random_str
        
    def __setitem__(self, key, value):
        if self.random_str == None:
            random_str = self.Handler.get_cookie(‘uc‘)
            if not self.random_str:
                random_str = self.__genarate_random_str()
                container[random_str] = {}
                
            else:
                if self.random_str in container.keys():
                    pass
                else:
                    random_str = self.__genarate_random_str()
                    container[random_str] = {}
            self.random_str = random_str
            
        container[self.random_str][key] = value
        # 瀏覽器寫入Cookie
        self.Handler.set_cookie(‘uc‘, self.random_str)
        
    def __getitem__(self, key):
        random_str = self.Handler.get_cookie(‘uc‘)
        if not random_str:
            return None
        user_info_dict = container.get(random_str, None)
        if not user_info_dict:
            return None
        value = user_info_dict.get(key, None)
        return value
        
class BashHandler(tornado.web.RequestHandler):
    def initialize(self):
        self.session = Session(self)
        
class SetHandler(BashHandler):
    def get(self, *args, **kwargs):
        self.session[‘Hello‘] = ‘World‘
        self.write(‘OK‘)
        
class GetHandler(BashHandler):
    def get(self, *args, **kwargs):
        val = self.session[‘Hello‘]
        self.write(val)
        
application = tornado.web.Application([
    (r‘/set‘, SetHandler),
    (r‘/get‘, GetHandler),
])
if __name__ == ‘__main__‘:
    print(‘http://127.0.0.1:8000‘)
    application.listen(8000)
    tornado.ioloop.IOLoop.instance().start()

#Python全棧之路 #Session #Cookie #Tornado


2Python全棧之路系列之Tornado的Cookie與Sess