1. 程式人生 > >Web框架系列:Session的實現原理

Web框架系列:Session的實現原理

  WEB應用都很依賴session這一功能。不少同學不明白session的原理,其實,session實現起來非常簡單。HTTP協議是無狀態了,每次訪問一個資源,就發起一次連線,得倒資源後,就關閉了連線。瀏覽器和伺服器就無法聯絡了。所以,伺服器為了認證瀏覽器的身份,需要讓瀏覽器攜帶一個獨一無二的信令,其他人無法獲取到,也沒有辦法猜測到,每次瀏覽器來訪問自己的時候都帶上這個信令,伺服器判斷這個信令是不是自己發出的,就可以知道瀏覽器是誰了。原理這就是這麼簡單。這個信令就是cookie了。
  session的依賴瀏覽器的cookie。cookie的生命週期是伺服器設定的。我們想要的效果是,如果使用者關閉瀏覽器,離開了電腦,別人就不能再啟動瀏覽器,開啟之前的頁面進入的系統了。HTTP Response裡的expires域可指定Cookie的生命週期。如果不設定expires或者max-age這個cookie預設是Session的,也就是關閉瀏覽器該cookie就消失了。就相當於與這個信令永遠的從這個世界上消失了。但是,父短短並不知道使用者已經下線,所以,在服務端一般需要對Session設定一個生存期限。比如Tomcat預設是30分鐘。30分鐘內沒有攜帶這個信令的訪問來到,就需要釋放session,避免佔用記憶體。那如何實現呢?
   Java有Tomcat這樣的Web容器,Session管理工作由容器來完成,session一般也常駐記憶體。Tomcat中有常駐程序,可以在常駐程序裡每一秒中就判斷一下,看看每一個session的最後訪問時間距離現在是否超過了30分鐘,如果超過了,就釋放session。
   PHP沒有容器這個概念,沒有常駐後臺程序的,也就是沒有辦法由容器主動的釋放session,需要Application自己來做這個工作。注意,框架也屬於application的一部分。一般而言,都是框架來實現session的管理。在Laravel裡,由session保護的資源和非session保護的資源就需要自己手動分開。那如何實現釋放session呢?
  1,每一個資源訪問,都去遍歷一下session的容器,判斷最後訪問時間,超時的剔除。
  2,如果session實現方式是檔案,debian、ubuntu採用的方式更加暴力,使用/etc/cron.d/php5,定時的刪除檔案即可
​​​​​​​  如果使用OpenResty這樣的程式來實現,session是常駐記憶體的,但是沒有常駐程序,但一個nginx worker繫結一個VM,只能通過nginx提供的timer模組,定時的去訪問LuaVM中的session資料,也可以達到更新的目的。

  不少網站都有“一週內免登入”這樣的選項,就是改變了cookie的生命週期。讓上次瀏覽器關閉時cookie不被清除。這也是一個不安全的選項。

  1. http://www.blogjava.net/persister/archive/2010/08/24/329838.html
  2. http://blog.chinaunix.net/uid-7374279-id-2057534.html
  3. http://www.phpthinking.com/archives/318
  4. http://stackoverflow.com/questions/520237/how-do-i-expire-a-php-session-after-30-minutes
  5. http://stackoverflow.com/questions/654310/cleanup-php-session-files
    http://stackoverflow.com/questions/7842963/memcachephp-session-tuning-how-does-memcache-expire-keys