博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Tornado-Secure cookie and Session
阅读量:6578 次
发布时间:2019-06-24

本文共 6861 字,大约阅读时间需要 22 分钟。

这一节涉及的内容有:

1.客户端和服务端操作cookie的方法

2.secure cookie的机制

3.基本/自定义session

文件结构

三个启动文件由下往上对应的分别是三种服务端:使用secure cookie,使用基本的session,使用自定义session。

另外,这一节中的index.html中并任何实质的内容,我只是在里面练习写了一个服务端生成自定义时间的键值对cookie,同样附在下面

Python代码

start.py

from tornado import webimport tornado.ioloopclass IndexHandler(web.RequestHandler):    def get(self):        if self.get_argument('user', None) in ['yeff', 'mike']:            self.set_secure_cookie('n', self.get_argument('user'))            self.write('欢迎')        else:            self.write('请登陆')class ManagerHandler(web.RequestHandler):    def get(self):        # 注意这里取得的cookie是bytes格式的,不是字符串格式        if self.get_secure_cookie('n', None) in [b'yeff', b'mike']:            self.write('欢迎登陆: ' + str(self.get_secure_cookie('n'),encoding="utf-8"))        else:            self.redirect('/index')settings = {    "template_path": "views",    "static_path": "static",    "cookie_secret": "salt",}application = web.Application([    (r"/index", IndexHandler),    (r"/manager", ManagerHandler),], **settings)if __name__ == "__main__":    application.listen(8888)    tornado.ioloop.IOLoop.instance().start()
使用secure cookie的服务端

 

session-start.py

还有很大的缺陷,如登陆后再装到index还是会提示未登陆。这一点在自定义session中有修正。

from tornado import webimport tornado.ioloopimport timeimport hashlibsessions = {}# 可以注意到在用了session后,每次重启客户端后,用户拿着cookie也是没有办法登陆的# 因为客户端这边的sessions中的内容被清空了,好比用户手里虽然还有钥匙(cookie键值对)# 但服务端的箱子已经没有了# 当然sessions可以放在数据库/文件/缓存中,而不是存储在内存中# cookie是否使用完全看服务端的需求:只要将对应user的islogin信息换成False即可# 通过在服务端和cookie间多添加一层抽象,既便于存储大量信息,也提升了安全性class IndexHandler(web.RequestHandler):    def get(self):        if self.get_argument('usn', None) in ['yeff', 'mike']:            _en = hashlib.md5()            _en.update(bytes(str(time.time()), encoding="utf-8"))            user_key = _en.hexdigest()            sessions[user_key] = {}            sessions[user_key]['name'] = 'Yifei Xu'            sessions[user_key]['age'] = '23'            sessions[user_key]['accountInfo'] = 'xyfst'            sessions[user_key]['isLogin'] = True            self.set_cookie(name='steam', value=user_key)            self.write('登陆成功了哦@_@')        else:            self.write('请登陆-_-')class ManagerHandler(web.RequestHandler):    def get(self):        user_key = self.get_cookie(name='steam')        user_info = sessions.get(user_key)        if not user_info:            self.redirect("/index")        else:            if user_info.get('isLogin'):                display_str = "Name:%s\tAge:%s\tAccount:%s" % (user_info.get('name'), user_info.get('age'), user_info.get('accountInfo'))                self.write(display_str)            else:                self.write("登陆信息已失效,得重新登陆啦*_*")settings = {    "template_path": "views",    "static_path": "static",}application = web.Application([    (r"/index", IndexHandler),    (r"/manager", ManagerHandler),], **settings)if __name__ == "__main__":    application.listen(8888)    tornado.ioloop.IOLoop.instance().start()
使用基本session的服务端

 class-session-start.py

from tornado import webimport tornado.ioloopSESSIONS = {}class Sessions(object):    def __init__(self, handler, cookie_key):        self.handler = handler        self.user_key = None        self.cookie_key = cookie_key    @staticmethod    def generate_random_str():        import hashlib, time        _en = hashlib.md5()        _en.update(bytes(str(time.time()), encoding="utf-8"))        return _en.hexdigest()    def __setitem__(self, k, v):        # 创建随机字符串        # 创建自己的箱子        # 在箱子中放入信息对        # 在客户端中放入箱子的钥匙        # 如果服务端还没有钥匙,先制作一个钥匙,并创建一个对应的箱子        if not SESSIONS.get(self.user_key):            self.user_key = Sessions.generate_random_str()            SESSIONS[self.user_key] = {}        # 起初/manager页面无论如何都无法进入,想了很久        # 这个点费了我不少时间才找到:这边对SESSIONS中是否存在钥匙没有判断,使得每次set方法清空钥匙对应的箱子        SESSIONS[self.user_key][k] = v        self.handler.set_cookie(self.cookie_key, self.user_key)    def __getitem__(self, item):        # 获取客户端递来的钥匙        # 看看房间里有对应钥匙吗        # 用钥匙打开箱子,获得信息对,取出值        # 没有钥匙返回None        value = None        _user_key = self.handler.get_cookie(self.cookie_key)        if SESSIONS.get(_user_key):            self.user_key = _user_key            value = SESSIONS[self.user_key][item]        return value# IndexHandler和ManagerHandler都继承这个类# tornado为我们留的钩子,使用继承RequestHandler的类并初始化时(执行__init__方法),会在最后执行 self.initialize(**kwargs)# 我们可以自己定义initialize的函数内容,以实现不同的效果# 这里我们是初始化了服务端的Sessions类,继承之后,两个类就不用自己再初始化了,更简洁一些class BaseHandler(web.RequestHandler):    def initialize(self):        self.session = Sessions(self, 'steam')# tornado内部通过反射调用get和post方法# obj = IndexxHandler()# func = getattr(obj, "get")# func()class IndexHandler(BaseHandler):    def get(self):        # 如果客户端有对应的钥匙则转到manager页面尝试匹配        if SESSIONS.get(self.get_cookie('steam')):            self.redirect('/manager')        # 注意这里的多层嵌套        # 第一次我将两个if写在了同级,但在执行了redirect函数后,还是会接着执行下面判断中的else块        # 虽不至于中止程序,但会报错,所以这里写成了两层嵌套        else:            # 判断用户登陆信息是否正确(这里作了简化,只判断了用户名)            if self.get_argument('usn', None) in ['yeff', 'mike']:                # session = Sessions(self, 'steam')                self.session['isLogin'] = True                self.session['name'] = 'Yifei Xu'                self.session['age'] = '23'                self.session['accountInfo'] = 'xyfst'                self.write('登陆成功了哦@_@')            else:                self.write('请先登陆呦')class ManagerHandler(BaseHandler):    def get(self):        # session = Sessions(self, 'steam')        # 从客户端拿来钥匙        # 看看服务端的房间里有钥匙吗        # 有则取出对应的信息对        _site_user_key = self.get_cookie(self.session.cookie_key)        if not SESSIONS.get(_site_user_key):            self.write('登陆信息已失效,请先登陆*。*')        else:            display_str = "Name:%s\tAge:%s\tAccount:%s" % (self.session['name'], self.session['age'], self.session['accountInfo'])            self.write(display_str)settings = {    "template_path": "views",    "static_path": "static",}application = web.Application([    (r"/index", IndexHandler),    (r"/manager", ManagerHandler),], **settings)if __name__ == "__main__":    application.listen(8888)    tornado.ioloop.IOLoop.instance().start()
使用自定义session的服务端

 HTML代码

index.html

并没有实质的实际内容,内部只有一个我自己写的生成自定义cookie的方法

 

    
Title

Cookie

浏览器端生成自定义cokie

 

额外内容

这一节也涉及到了python类的特殊方法以及钩子函数,在注释里都有讲到,下面也附带一些解释。

class Foo:    def __call__(self, *args, **kwargs):        pass        def __init__(self):        pass        def __class__(self):        pass        def __setitem__(self, key, value):        pass        def __getitem__(self, item):        pass        def __delitem__(self, key):        pass        obj = Foo()       # __call__, __init__obj['k1'] = 'v1'  # __setitem__obj['k1']         # __getitem__del obj['k1']     # __delitem__

 

钩子函数: http://blog.csdn.net/sunstars2009918/article/details/39340449(这位作者讲的很清晰,虽然例子是C。*-*)

 

转载于:https://www.cnblogs.com/yifeixu/p/8028908.html

你可能感兴趣的文章
响应式编程
查看>>
Spring Cloud--Honghu Cloud分布式微服务云系统—组件化
查看>>
java多线程 帖子一览
查看>>
solidity智能合约[6]-基本类型与bool运算
查看>>
Java虚拟机
查看>>
Istio技术与实践02:源码解析之Istio on Kubernetes 统一服务发现
查看>>
2019的第一天
查看>>
python 语言基础之切片,迭代
查看>>
触摸复习,CALayer
查看>>
WPS文件格式怎么转换成PDF格式
查看>>
一文彻底读懂Java虚拟机!(JVM)
查看>>
初学Linux第二周小记
查看>>
(详细)华为荣耀10 COL-AL10的usb调试模式在哪里开启的步骤
查看>>
学习Python,is和==的本质区别你知道吗?
查看>>
阿里巴巴数据分析沙龙 杭州站圆满召开
查看>>
云视频会议如何做到参会人脸识别?
查看>>
选择能达到要求的扫描头
查看>>
C语言模拟实现多态
查看>>
公开课(视频)|聊聊 Http 协议和我们日常工作的关系
查看>>
Linux下安装LoadRunner LoadGenerator
查看>>