1、通过签名防止cookie篡改
import tornado.httpserver
import tornado.ioloop
import tornado.web
import tornado.options
from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)
class MainHandler(tornado.web.RequestHandler):
def get(self):
cookie = self.get_secure_cookie("count")
count = int(cookie) + 1 if cookie else 1
countString = "1 time" if count == 1 else "%d times" % count
self.set_secure_cookie("count", str(count))
self.write(
'<html><head><title>Cookie Counter</title></head>'
'<body><h1>You’ve viewed this page %s times.</h1>' % countString +
'</body></html>'
)
if __name__ == "__main__":
tornado.options.parse_command_line()
settings = {
"cookie_secret": "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E="
}
application = tornado.web.Application([
(r'/', MainHandler)
], **settings)
http_server = tornado.httpserver.HTTPServer(application)
http_server.listen(options.port)
tornado.ioloop.IOLoop.instance().start()
Tornado将cookie值编码为Base-64字符串,并添加了一个时间戳和一个cookie内容的HMAC签名。如果cookie的时间戳太旧(或来自未来),或签名和期望值不匹配,get_secure_cookie()函数会认为cookie已经被篡改,并返回None,就好像cookie从没设置过一样。cookie值是签名的而不是加密的。
2、使用HTTP-Only和SSL Cookies属性保证cookie安全
HTTP-Only属性:禁止JavaScript访问cookie
SSL Cookies属性:指示浏览器只通过SSL连接传递cookie
用法:
self.set_cookie('foo', 'bar', httponly=True, secure=True)
self.set_secure_cookie('foo', 'bar', httponly=True, secure=True)
3、防止cookie的跨站访问攻击
通过在应用的构造函数中包含xsrf_cookies参数来开启XSRF保护:
settings = {
"cookie_secret": "bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E=",
"xsrf_cookies": True
}
application = tornado.web.Application([
(r'/', MainHandler),
(r'/purchase', PurchaseHandler),
], **settings)
当这个应用标识被设置时,Tornado将拒绝请求参数中不包含正确的_xsrf值的POST、PUT和DELETE请求。Tornado将会在幕后处理_xsrf cookies,但你必须在你的HTML表单中包含XSRF令牌以确保授权合法请求。要做到这一点,只需要在你的模板中包含一个xsrf_form_html调用即可:
<form action="/purchase" method="POST">
{% raw xsrf_form_html() %}
<input type="text" name="title" />
<input type="text" name="quantity" />
<input type="submit" value="Check Out" />
</form>
AJAX请求也需要一个_xsrf参数
jQuery.postJSON = function(url, data, callback) {
data._xsrf = getCookie("_xsrf");
jQuery.ajax({
url: url,
data: jQuery.param(data),
dataType: "json",
type: "POST",
success: callback
});
}