2Python全栈之路系列之Tornado的Cookie与Sess

Python全栈之路系列之Tornado的Cookie与Sess


主要的代码结构为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#!/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的操作

COokie是保存在浏览器的一个键值对,每次的HTTP请求都会携带Cookie

获取所有的Cookies

1
self.cookies

设置Cookie

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

可接受的参数描述:

参数 描述
name Cookie的Key
value Cookie的value
domain 生效的域名
expires 以秒为过期时间,默认从1970-01-01T00:00:10.000Z
path 生效路径
expires_days 以天数过期时间,如果设置为None则关闭浏览器Cookie就失效

设置cookie过期时间为15分钟以后的代码为:

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

MainHandler的代码

1
2
3
4
5
6
7
8
9
10
11
12
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,你需要在创建应用时提供一个**,名字为cookie_secret, 你可以把它作为一个关键词参数传入应用的设置中:

1
2
3
application = tornado.web.Application([
    (r'/', MainHandler),
], cookie_secret="508CE6152CB93994628D3E99934B83CC")

设置一个加密Cookie所需要的参数

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

参数和上面的大同小异。

MainHandler的代码

1
2
3
4
5
6
7
8
9
10
11
12
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流程:

写cookie过程:

  1. 将值进行base64加密

  2. 对除值以外的内容进行签名,哈希算法(无法逆向解析)

  3. 拼接 签名 + 加密值

读cookie过程:

  1. 读取签名 + 加密值

  2. 对签名进行验证

  3. base64解密,获取值内容

基于Cookie的用户登陆实例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 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文件内容

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 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>

演示结果如下:
2Python全栈之路系列之Tornado的Cookie与Sess

Session

Tornado中是不提供像Cookie这种直接设置Session的,需要我们自己写插件来进行对Session的增删改

Session的数据是保存在服务端的,如果要应用Session必须要依赖Cookie,因为Cookie的值就等于Session的Key

Session在内存中的存储方式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
key(随机字符串) = {
    {'k1','v1'},
    {'k2','v2'},
    {'k3','v3'},
    ....
}
 
key(随机字符串) = {
    {'k1','v1'},
    {'k2','v2'},
    {'k3','v3'},
    ....
}
 
key(随机字符串) = {
    {'k1','v1'},
    {'k2','v2'},
    {'k3','v3'},
    ....
}
.....

一个设置与获取Session的小脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#!/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()









本文转自 Edenwy  51CTO博客,原文链接:http://blog.51cto.com/edeny/1925121,如需转载请自行联系原作者