关于cookie在web工程中的作用请阅读我的另一篇文章flask web开发中使用cookie,本文不对cookie概念再做介绍,而是专注于讲解tornado中如何使用cookie
在tornaod中设置cookie值使用set_cookie方法,使用get_cookie获取cookie值,下面的例子将使用cookie保存不同用户上一次的访问时间
from datetime import datetime, timedelta
import tornado.ioloop
from tornado.web import RequestHandler, Application
from tornado.httpserver import HTTPServer
from tornado.options import options, define
define('port', default=8000, help='监听端口')
class HelloHandler(RequestHandler):
def get(self, name):
last_access_time = self.get_cookie(name)
self.set_cookie(name, datetime.now().strftime("%Y-%m-%dT%H:%M:%S"))
if last_access_time:
self.finish(f'welcome {name}, you last access time is {last_access_time}')
else:
self.finish(f'welcome {name} you access this web first time')
if __name__ == '__main__':
options.parse_command_line()
handlers_routes = [
(r'/(.*)', HelloHandler)
]
app = Application(handlers=handlers_routes)
http_server = HTTPServer(app)
http_server.listen(options.port)
tornado.ioloop.IOLoop.current().start()
在设置cookie值时,我将时间转为“2021-11-11T19:18:46”, 在日期与小时之间有一个T,之所以这样做是因为tornado 会对cookie的值进行检查,如果cookie的value里包含ascii码里的前32个字符中的任意一个,则视为违法字符,对于key也是如此
name = escape.native_str(name)
value = escape.native_str(value)
if re.search(r"[\x00-\x20]", name + value):
# Don't let us accidentally inject bad stuff
raise ValueError("Invalid cookie %r: %r" % (name, value))
这样做的目的是为了预防XSS攻击,因此我不得不去掉时间字符串里的空格符,中间加一个T,这种格式是ISO 8601,后面应该加一个Z表示UTC时间,如果是北京时间则应该加“+0800”,这里我给省略了。
self.set_cookie(name, datetime.now().strftime("%Y-%m-%dT%H:%M:%S"), max_age=5)
max_age参数设置多少秒以后cookie过期,这是一个非常简便的设置过期的方法
expires 可以指定过期时间,这样可以精准的指定在某个特定的时间点过期
expires_time = datetime(year=2021, month=11, day=12, hour=18) - timedelta(hours=8)
self.set_cookie(name, datetime.now().strftime("%Y-%m-%dT%H:%M:%S"), expires=expires_time)
我希望cookie的过期时间设置在11月12号的18点,但expires要求传入的是UTC时间,因此我要在这个时间基础上减去8小时得到UTC时间。除了expires参数,还可以使用expires_days传入过期的天数,当expires没没有传值而expires_days有值传入时则将过期时间设置为当前UTC时间加上expires_days以后的时间。如果两个参数都不传,则默认过期时间为30天。
cookie的值可以在浏览器里查看,是可以被伪造的,如果你很在意cookie的安全性,可以使用set_secure_cookie方法设置cookie,使用此方法需要在创建application的时候设置cookie_secret 秘钥
app = Application(handlers=handlers_routes, cookie_secret='hard to guess')
获取cookie值的方法也要使用安全的get_secure_cookie
class HelloHandler(RequestHandler):
def get(self, name):
last_access_time = self.get_secure_cookie(name)
expires_time = datetime(year=2021, month=11, day=12, hour=18) - timedelta(hours=8)
self.set_secure_cookie(name, datetime.now().strftime("%Y-%m-%dT%H:%M:%S"), expires=expires_time)
if last_access_time:
self.finish(f'welcome {name}, you last access time is {last_access_time}')
else:
self.finish(f'welcome {name} you access this web first time')
只要秘钥不被泄露,那么就没有人可以伪造出cookie值欺骗你的网站。
QQ交流群: 211426309