这一节涉及的内容有:

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

2.secure cookie的机制

3.基本/自定义session

文件结构

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

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

Python代码

start.py

from tornado import web
import 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 web
import tornado.ioloop
import time
import 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'] = Trueself.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 web
import tornado.ioloopSESSIONS = {}class Sessions(object):def __init__(self, handler, cookie_key):self.handler = handlerself.user_key = Noneself.cookie_key = cookie_key@staticmethoddef 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] = vself.handler.set_cookie(self.cookie_key, self.user_key)def __getitem__(self, item):# 获取客户端递来的钥匙# 看看房间里有对应钥匙吗# 用钥匙打开箱子,获得信息对,取出值# 没有钥匙返回Nonevalue = None_user_key = self.handler.get_cookie(self.cookie_key)if SESSIONS.get(_user_key):self.user_key = _user_keyvalue = 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'] = Trueself.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的方法

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body><h1>Cookie</h1>
<script><!--根据用户输入设置cookie,时间单位可以是yMdhms,格式是数字+对应字母--><!--也可以针对不同单位的时间分开写方法,我这里整合为了一种方法,顺便复习了js的字符串操作方法以及switch语法-->function setCookie(name,value,expires){var current_date = new Date();if(typeof(expires) == 'string'){var unit = expires.charAt(expires.length-1);var str_num = expires.slice(0,expires.length-1);var num = parseInt(str_num);if('yMdhms'.includes(unit) && num){switch(unit){case 'y':current_date.setDate(current_date.getDate() + num * 365);case 'M':current_date.setDate(current_date.getDate() + num * 30);case 'd':current_date.setDate(current_date.getDate() + num);case 'h':current_date.setSeconds(current_date.getSeconds() + num * 60 * 60);case 'm':current_date.setSeconds(current_date.getSeconds() + num * 60);case 's':current_date.setSeconds(current_date.getSeconds() + num);}}else{return false;}}else{return false;}document.cookie = name + "=" + value + ";expires=" + current_date.toUTCString();return true;}</script>
</body>
</html>

浏览器端生成自定义cokie

额外内容

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

class Foo:def __call__(self, *args, **kwargs):passdef __init__(self):passdef __class__(self):passdef __setitem__(self, key, value):passdef __getitem__(self, item):passdef __delitem__(self, key):passobj = 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

Tornado-Secure cookie and Session相关推荐

  1. tornado 09 cookie和session

    tornado 09 cookie和session 一.cookie #有什么办法能够让浏览器记住登录信息,下次再打开的时候可以自动登录?网站是如何记录登录信息的? class SetCookieHa ...

  2. Django之Cookie、Session、CSRF、Admin

    Django之Cookie.Session.CSRF.Admin Cookie 1.获取Cookie: 1 2 3 4 5 6 request.COOKIES[ 'key' ] request.get ...

  3. web存储中cookie、session区别

    http协议是一种无状态的协议,浏览器对服务器的每一次请求都是独立的.为了使得web能够产生一些动态信息,就需要保存"状态",而cookie和session机制就是为了解决http ...

  4. 关于cookie的文章(cookie与session机制)

    会话(Session)跟踪是Web程序中常用的技术,用来跟踪用户的整个会话.常用的会话跟踪技术是Cookie与Session.Cookie通过在客户端记录信息确定用户身份,Session通过在服务器端 ...

  5. Cookie与 Session使用详解

    1.Cookie和Session简介与区别 在非常多时候,我们需要跟踪浏览者在整个网站的活动,对他们身份进行自动或半自动的识别(也就是平时常说的网站登陆之类的功能),这时候,我们常采用Cookie与 ...

  6. cookie和session的那些事儿

    COOKIE介绍 cookie 常用于识别用户.cookie 是服务器留在用户计算机中的小文件.每当相同的计算机通过浏览器请求页面时,它同时会发送 cookie.通过 PHP,您能够创建并取回 coo ...

  7. Django框架详细介绍---cookie、session、自定义分页

    1.cookie 在HTTP协议介绍中提到,该协议是无状态的,也就是每次请求都是独立的,它的执行情况和结果与前面的请求和之后的请求都无直接关系,它不会受前面的请求响应情况直接影响,也不会直接影响后面的 ...

  8. python如何使用session和cookie_django进阶之cookie和session的使用示例

    Cookies :是浏览器为 Web 服务器存储的一小段信息. 每次浏览器从某个服务器请求页面时,它收到服务器回发送过来的cookies.它保存在浏览器下的某个文件夹下. Session:Django ...

  9. (进阶篇)Cookie与 Session使用详解

    1.Cookie和Session简介与区别 在非常多时候,我们需要跟踪浏览者在整个网站的活动,对他们身份进行自动或半自动的识别(也就是平时常说的网站登陆之类的功能),这时候,我们常采用Cookie与 ...

最新文章

  1. [转] Gradle: 此时不应有 Androidandroid-studiosdk oolslib\find_java.exe。解决方法
  2. RabbitMQ(十):RabbitMQ 如何保证消息的可靠性
  3. 微信小程序 html modal,微信小程序参考微信设计规范做的modal模态框
  4. 【Java爬虫】我的第一个爬虫 -- 简单抓取网页源代码
  5. was java sdk_关于WAS9单独安装SDK的问题?
  6. superset 时区问题Timestamp subtraction must have the same timezones or no timezones
  7. 有人去瑞幸咖啡java_瑞幸股价暴跌,门店竟然爆单了
  8. mysql递归自身连接_Mysql递归连接
  9. c语言学生综合测评系统_综合测评线上系统帮助文档
  10. 使用 SqlDependency 对象缓存数据以提高性能
  11. b站 前端构架_技术干货:哔哩哔哩(B站)功能框架图
  12. 光纤光信号闪红灯_激光放大器在光纤领域的应用
  13. Python 水仙花数练习
  14. 应用统计学与计算机论文,浅谈统计学在生活中的应用
  15. 惯性导航算法(三)-方向余弦矩阵(下)
  16. 关于html引用css无法加载——新手踩的坑
  17. Neo4j 启动报错 Server shutdown initiated by request
  18. linux的炒股软件“全胜”
  19. 一招解决LoadRunner不能录制脚本(录制脚本为空)问题
  20. ATF源码篇(十):docs文件夹-Components组件(9)Measured Boot Driver (MBD)

热门文章

  1. Zabbix4.2监控nginx状态
  2. List的【addAll(List list)】方法
  3. app内嵌h5页面在ios手机端滑动卡顿的解决方法
  4. eclipse代码自动提示设置、如何配置eclipse的代码自动提示功能(同时解决自动补全变量名的问题)?
  5. 按值对对象属性进行排序
  6. Java的“ for each”循环如何工作?
  7. mysql not in 的坑 -- null 值
  8. cf烟雾头怎么调win7系统
  9. 利用旧服务器制作存储资源池,想将存储系统整合,又想实现存储资源池化?
  10. mysql中有exist吗_关于MySQL 中 EXISTS 的用法