目前大多數服務器判斷用戶是否登錄一般通過session機制,Tornado 通過 set_secure_cookie 和 get_secure_cookie 方法直接支持了這種功能。原理類似於session,只不過session是服務器自動生成一個sessionID存儲在cookie里,而tornado需要我們手工設cookie。然后通過self.current_user的重載函數就可以實現用戶的驗證。
首先來看下set_secure_cookie和get_secure_cookie的使用方法:
Tornado的set_secure_cookie()和get_secure_cookie()函數發送和取得瀏覽器的cookies,以防范瀏覽器中的惡意修改。為了使用這些函數,你必須在應用的構造函數中指定cookie_secret參數。讓我們來看一個簡單的例子。這個例子將統計瀏覽器中頁面被加載的次數。如果沒有設置cookie或者cookie被篡改了,應用將設置一個值為1的新cookie,否則應用將從cookie中讀到的值加1
class MainHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
cookie=self.get_secure_cookie("count")
print cookie
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))
content='you have viewed this page %s times' % countstring
print content
self.write(content)
def server_function():
cookie='bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E='
tornado.options.parse_command_line()
app = tornado.web.Application(handlers=[(r"/", MainHandler),(r"/show",showHandler),(r"/index1",indexHandler_temp)],template_path=os.path.join(os.path.dirname(__file__),"template"),
static_path=os.path.join(os.path.dirname(__file__),"static"),ui_modules={'Book':HelloModule},cookie_secret=cookie)
http_server = tornado.httpserver.HTTPServer(app)
http_server.listen(options.port,address='127.0.0.1')
tornado.ioloop.IOLoop.instance().start()
首先來運行看下結果:
在瀏覽器中輸入url,可以看到顯示的是瀏覽了一次網站
來看下服務器后端的打印。首先通過self.get_secure_cookie("count")得到的的cookie值是None,也就是空的。此時訪問次數的賦值是count=int(cookie) + 1 if cookie else 1,在cookie為空的時候,count=1, 否則是int(cookie)+1. 最終通過self.set_secure_cookie("count",str(count))將更新好的count值以及cookie值再帶給服務器。cookie值是通過在Application中設置的cookie='bZJc2sWbQLKos6GkHn/VB9oXwQt8S0R0kRvJ5/xJ89E='
/usr/bin/python2.7 /home/zhf/py_prj/tornada_try.py
None
you have viewed this page 1 time times
[I 180103 10:50:10 web:2063] 200 GET / (127.0.0.1) 0.92ms
不停的刷新瀏覽器,可以看到對應的count值也在不斷的積累,通過這個我們就能監控到訪問的網站的次數。
/usr/bin/python2.7 /home/zhf/py_prj/tornada_try.py
None
you have viewed this page 1 time times
[I 180103 10:50:10 web:2063] 200 GET / (127.0.0.1) 0.92ms
[I 180103 10:56:59 web:2063] 200 GET / (127.0.0.1) 0.62ms
1
you have viewed this page 2 times times
[I 180103 10:57:09 web:2063] 200 GET / (127.0.0.1) 0.57ms
2
you have viewed this page 3 times times
3
you have viewed this page 4 times times
[I 180103 10:57:11 web:2063] 200 GET / (127.0.0.1) 2.03ms
4
[I 180103 10:57:12 web:2063] 200 GET / (127.0.0.1) 2.08ms
you have viewed this page 5 times times
[I 180103 10:57:13 web:2063] 200 GET / (127.0.0.1) 2.06ms
5
you have viewed this page 6 times times
6
you have viewed this page 7 times times
[I 180103 10:57:14 web:2063] 200 GET / (127.0.0.1) 2.24ms
7
you have viewed this page 8 times times
[I 180103 10:57:14 web:2063] 200 GET / (127.0.0.1) 2.31ms
在瀏覽器也可以查看到服務器發下來的cookie值,其中攜帶了count值
但是如果我們在瀏覽器上刪除了這個cookie值,我們來看下運行的結果如何:
我們看到訪問的次數又變成1了。
再看下服務器端的打印:之前訪問的次數是11次,由於在瀏覽器上刪除了cookie值,因此獲得的count值為None,因此又重新計數。
10
you have viewed this page 11 times times
[I 180103 11:03:57 web:2063] 200 GET / (127.0.0.1) 0.59ms
[W 180103 11:03:57 web:2063] 404 GET /favicon.ico (127.0.0.1) 1.24ms
None
you have viewed this page 1 time times
[I 180103 11:04:19 web:2063] 200 GET / (127.0.0.1) 0.44ms
[W 180103 11:04:19 web:2063] 404 GET /favicon.ico (127.0.0.1) 0.50ms
同樣的如果在MainHandler中添加清除cookie的命令self.clear_cookie("count")。那么瀏覽器的訪問次數將永遠是1
class MainHandler(tornado.web.RequestHandler):
def get(self, *args, **kwargs):
cookie=self.get_secure_cookie("count")
print cookie
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))
content='you have viewed this page %s times' % countstring
print content
self.write(content)
self.clear_cookie("count")
運行結果:
None
you have viewed this page 1 time times
[I 180103 11:08:50 web:2063] 200 GET / (127.0.0.1) 2.12ms
None
you have viewed this page 1 time times
[I 180103 11:08:51 web:2063] 304 GET / (127.0.0.1) 1.62ms
[I 180103 11:08:51 web:2063] 304 GET / (127.0.0.1) 1.94ms
None
you have viewed this page 1 time times
Tornado的cookie功能依附於Python內建的Cookie模塊。因此,我們可以利用它所提供的一些安全功能。這些安全屬性是HTTP cookie規范的一部分,並在它可能是如何暴露其值給它連接的服務器和它運行的腳本方面給予瀏覽器指導。比如,我們可以通過只允許SSL連接的方式減少cookie值在網絡中被截獲的可能性。我們也可以讓瀏覽器對JavaScript隱藏cookie值。
為cookie設置secure屬性來指示瀏覽器只通過SSL連接傳遞cookie。(這可能會產生一些困擾,但這不是Tornado的安全cookies,更精確的說那種方法應該被稱為簽名cookies。)從Python 2.6版本開始,Cookie對象還提供了一個httponly屬性。包括這個屬性指示瀏覽器對於JavaScript不可訪問cookie,這可以防范來自讀取cookie值的跨站腳本攻擊。
為了開啟這些功能,你可以向set_cookie和set_secure_cookie方法傳遞關鍵字參數。比如,一個安全的HTTP-only cookie(不是Tornado的簽名cookie)可以調用self.set_cookie('foo', 'bar', httponly=True, secure=True)發送。
有興趣的可以搭建一個https網站去嘗試下。