玩蛇記-給tornado加上session支援

來源:互聯網
上載者:User

WARNING!

閱讀本文需要具有使用python編程的能力以及Web編程的經驗,起碼應該知道python是什麼,Session是什麼。初學者慎入,某些描述語焉不詳,小心誤入歧途,歡迎高手踴躍拍磚。本文代碼僅僅作為樣本使用,用於說明在tornado中實現session的過程以及方法,未經過任何編譯或者運行,請勿直接copy到項目中使用,本人不對此行為造成的後果負任何責任。(此文實現內容來源於商業項目,恕未能直接提供源碼)

----------------------------------------------------------

tornado沒有提供預設的會話,而很多敏感資訊又沒法用cookie存,tornado提供的secure_cookie只是解決了防止cookie篡改而沒法阻止資料被解密為明文,所以我就給tornado寫了一個session的包來解決這個問題。嗯,我們來看看是如何從底層一磚一瓦的來實現Session的功能。

根據項目的需要我採用Memcached作為Session的backend,當然你願意用Mysql或者是其他什麼能儲存資料的東西都行,比如文字檔或者mongodb,選擇很多,所以我們將Session需要持久化的操作獨立出來成為一個可以替換的backend模組,我們可以根據配置使用不同的backend,由於python得ducktyping特性,要實現起來相當的簡單,我們只需要提供包含如下三個方法簽名的類就行了

class backend():

    def getitem(self,key):

    def setitem(self,key,value,timeout)

    def deleteitem(self,key)

 

對於Memcached我們需要在backend類中保持一個Memcached的串連,大體上的實現如下:

from memcache import Client

class backend():

   def __init__(self):

        self.conn=Client([‘127.0.0.1:11211’])

   def getitem(self,key):

        return self.conn.get(key)

   def setitem(self,key,value,timeout):

        self.conn.set(key,value,timeout)

   def deleteitem(self,key):

        self.conn.delete(key)

當然實際應用中我們不會寫得這麼簡陋了,已連線的服務器資訊都是從設定檔裡取得的。這樣我們就有了一個Session的backend了,如果你想用Mysql作為backend,那麼可以按照這個原理來改寫一個backend類

有了Session資料的持久化backend後我們就可以開始編寫Session類本身了,首先我們來回顧一下Session的工作原理。基本上大部分的Session都是通過Cookie佈建服務端持久化來實現Session的,cookie保持使用者建立會話的SessionID,然後在每次訪問的時候通過SessionID到持久化服務中去取這個Session的資料。當一個request開始的時候過程如:

當一個request結束之後,過程如:

 

理清楚處理的邏輯我們就能開始編碼了,首先我們需要用一個對象來儲存Session的資料,一般來說Session都按照Key-Value的形式儲存,所以我們可以用一個Dict來作為Session的儲存物件,但是我們還需要一個Session ID,所以我們繼承一個dict

class SessionData(dict):

    def __inti__(self,id=none):

        self.id=id

    def __getitem__(self,key):

        if self.has_key(key):

             return self[key]

        return None

    def __setitem__(self,key,value):

        self[key]=value

然後我們實現一個decorator來在一個request前和request後來恢複和儲存Session

def Session(request):

     def Process(handler,*args):

          #請求前恢複Session對象的過程

          item=handler.application.backend.getitem(handler.get_secure_cookie(‘session_id’,’’))

          data=None

          if item:

               data=new SessionData(item.id)

               data.update(item)

          else:

               data=new SessionData()

               handler.set_secure_cookie(“session_id”,””)

          handler.setattr(“session”,data)

          request(handler,*args)#執行原本請求的方法

          #請求完成後儲存session的過程

          if data.id:

               handler.application.backend.setitem(data.id,data)

          else:

               if len(data.keys()):

                    data.id=str(uuid1.uuid1())

                    handler.set_secure_cookie(“session_id”,data.id)

                    handler.application.backend.setitem(data.id,data)

 

這個方法有點長,不過邏輯就是這麼樣子的,實現了這個decreator之後我們只需要在需要使用Session的請求前加上@Session,就能夠通過self.session來使用session咯。

 

接下來想在項目裡使用還有一些具體的問題要解決,但是基本原理和實現方式在本文的內容就到此為止了,接下來的工作應該難不倒能看懂此文的同學,如果看著如同天書,那麼多半是對python或者tornado沒有什麼瞭解,請自行彌補基礎知識。希望此文能夠對正在實踐python和tornado的TX有所幫組

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.