1. 程式人生 > >理解Cookie和Session的區別及使用

理解Cookie和Session的區別及使用

前言

  • HTTP是一種無狀態的協議,為了分辨連結是誰發起的,需自己去解決這個問題。不然有些情況下即使是同一個網站每開啟一個頁面也都要登入一下。而Session和Cookie就是為解決這個問題而提出來的兩個機制。

應用場景

  • 登入網站,今輸入使用者名稱密碼登入了,第二天再開啟很多情況下就直接打開了。這個時候用到的一個機制就是cookie。
  • session一個場景是購物車,添加了商品之後客戶端處可以知道添加了哪些商品,而伺服器端如何判別呢,所以也需要儲存一些資訊就用到了session。

1.Cookie

  • 通俗講,是訪問某些網站後在本地儲存的一些網站相關資訊,下次訪問時減少一些步驟。更準確的說法是:Cookies是伺服器在本地機器上儲存的小段文字並隨每一個請求傳送至同一伺服器,是在客戶端保持狀態的方案。
  • Cookie的主要內容包括:名字,值,過期時間,路徑和域。使用Fiddler抓包就可以看見,比方說我們開啟百度的某個網站可以看到Headers包括Cookie,如下: 


    BIDUPSID: 9D2194F1CB8D1E56272947F6B0E5D47E 
    PSTM: 1472480791 
    BAIDUID: 3C64D3C3F1753134D13C33AFD2B38367:FG 
    ispeed_lsm: 2 
    MCITY: -131: 
    pgv_pvi: 3797581824 
    pgv_si: s9468756992 
    BDUSS: JhNXVoQmhPYTVENEdIUnQ5S05xcHZMMVY5QzFRNVh5SzZoV0xMVDR6RzV-bEJZSVFBQUFBJCQAAAAAAAAAAAEAAACteXsbYnRfY2hpbGQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAALlxKVi5cSlYZj 
    BD_HOME: 1 
    H_PS_PSSID: 1423_21080_17001_21454_21408_21530_21377_21525_21193_21340 
    BD_UPN: 123253 
    sug: 3 
    sugstore: 0 
    ORIGIN: 0 
    bdime: 0

  • key, value形式。過期時間可設定的,如不設,則瀏覽器關掉就消失了,儲存在記憶體當中,否則就按設定的時間來儲存在硬碟上的,過期後自動清除,比方說開關機關閉再開啟瀏覽器後他都會還存在,前者稱之為Session cookie 又叫 transient cookie,後者稱之為Persistent cookie 又叫 permenent cookie。路徑和域就是對應的域名,a網站的cookie自然不能給b用。

2.Session

  • 存在伺服器的一種用來存放使用者資料的類HashTable結構。
  • 瀏覽器第一次傳送請求時,伺服器自動生成了一HashTable和一Session ID來唯一標識這個HashTable,並將其通過響應傳送到瀏覽器。瀏覽器第二次傳送請求會將前一次伺服器響應中的Session ID放在請求中一併傳送到伺服器上,伺服器從請求中提取出Session ID,並和儲存的所有Session ID進行對比,找到這個使用者對應的HashTable。 
    • 一般這個值會有個時間限制,超時後毀掉這個值,預設30分鐘。
  • 當用戶在應用程式的 Web頁間跳轉時,儲存在 Session 物件中的變數不會丟失而是在整個使用者會話中一直存在下去。
  • Session的實現方式和Cookie有一定關係。建立一個連線就生成一個session id,開啟幾個頁面就好幾個了,這裡就用到了Cookie,把session id存在Cookie中,每次訪問的時候將Session id帶過去就可以識別了.

區別

  • 儲存資料量方面:session 能夠儲存任意的 java 物件,cookie 只能儲存 String 型別的物件
  • 一個在客戶端一個在服務端。因Cookie在客戶端所以可以編輯偽造,不是十分安全。
  • Session過多時會消耗伺服器資源,大型網站會有專門Session伺服器,Cookie存在客戶端沒問題。
  • 域的支援範圍不一樣,比方說a.com的Cookie在a.com下都能用,而www.a.com的Session在api.a.com下都不能用,解決這個問題的辦法是JSONP或者跨域資源共享。

session多伺服器間共享

  1. 伺服器實現的 session 複製或 session 共享,如 webSphere或 JBOSS 在搭叢集時配置實現 session 複製或 session 共享.致命缺點:不好擴充套件和移植。
  2. 利用成熟技術做session複製,如12306使用的gemfire,如常見記憶體資料庫redis或memorycache,雖較普適但依賴第三方.
  3. 將 session維護在客戶端,利用 cookie,但客戶端存在風險資料不安全,且可以存放的資料量較小,所以將session 維護在客戶端還要對 session 中的資訊加密。
  4. 第二種方案和第三種方案的合體,可用gemfire實現 session 複製共享,還可將session 維護在 redis中實現 session 共享,同時可將 session 維護在客戶端的cookie 中,但前提是資料要加密。

這三種方式可迅速切換,而不影響應用正常執行。在實踐中,首選 gemfire 或者 redis 作為 session 共享的載體,一旦 session 不穩定出現問題的時候,可以緊急切換 cookie 維護 session 作為備用,不影響應用提供服務

單點登入中,cookie 被禁用了怎麼辦?(一點登陸,子網站其他系統不用再登陸)

  • 單點登入的原理是後端生成一個 session ID,設定到 cookie,後面所有請求瀏覽器都會帶上cookie,然後服務端從cookie獲取 session ID,查詢到使用者資訊。
  • 所以,保持登入的關鍵不是cookie,而是通過cookie 儲存和傳輸的 session ID,本質是能獲取使用者資訊的資料。
  • 除了cookie,還常用 HTTP 請求頭來傳輸。但這個請求頭瀏覽器不會像cookie一樣自動攜帶,需手工處理