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多伺服器間共享
伺服器實現的 session 複製或 session 共享,如 webSphere或 JBOSS 在搭叢集時配置實現 session 複製或 session 共享.致命缺點:不好擴充套件和移植。
利用成熟技術做session複製,如12306使用的gemfire,如常見記憶體資料庫redis或memorycache,雖較普適但依賴第三方.
將 session維護在客戶端,利用 cookie,但客戶端存在風險資料不安全,且可以存放的資料量較小,所以將session 維護在客戶端還要對 session 中的資訊加密。
第二種方案和第三種方案的合體,可用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一樣自動攜帶,需手工處理

 

session原理:
1、session是儲存在伺服器端,理論上是沒有是沒有限制,只要你的記憶體夠大

 

2、瀏覽器第一次訪問伺服器時會建立一個session物件並返回一個JSESSIONID=ID的值,
   建立一個Cookie物件key為JSSIONID,value為ID的值,將這個Cookie寫回瀏覽器

 

3、瀏覽器在第二次訪問伺服器的時候攜帶Cookie資訊JSESSIONID=ID的值,如果該JSESSIONID的session已經銷燬,
   那麼會重新建立一個新的session再返回一個新的JSESSIONID通過Cookie返回到瀏覽器

 

4、針對一個web專案,一個瀏覽器是共享一個session,就算有兩個web專案部署在同一個伺服器上,針對兩個專案的session是不同的
   如:你在tomcat上同時部署了兩個web專案,分別是web1、web2。當你在一個瀏覽器上同時訪問web1時建立的session是A1,訪問web2時建立的session是A2。
       後面你再多次訪問web1使用的session還是A1,多次訪問web2時使用session就是A2

 

5、session是基於Cookie技術實現,重啟瀏覽器後再次訪問原有的連線依然會建立一個新的session,
   因為Cookie在關閉瀏覽器後就會消失,但是原來伺服器的Session還在,只有等到了銷燬的時間會自動銷燬

 

6、如果瀏覽器端禁用了Cookie,那麼每次訪問都會建立一個新的Session,但是我們可以通過伺服器端程式重寫URL即可,如果頁面多連線多,會增加不必要的工作量,
   那可以強制讓你使用者開啟接收Cookie後再讓其訪問即可。

 

    大白話:當你一次訪問伺服器的時候,伺服器會在記憶體中開闢一塊空間,返回唯一一把開啟該空間的鑰匙,再把這把鑰匙返回到瀏覽器。
            當你第二次訪問的時候瀏覽器會攜帶這把鑰匙到伺服器端開啟對應的空間,如果該空間已經銷燬又重新返回開闢一塊新的空間返回新的鑰匙到瀏覽器。

 


面試:
  
   說說Cookie和Session的區別?
   
   1、Cookie和Session都是會話技術,Cookie是執行在客戶端,Session是執行在伺服器端。
   
   2、Cookie有大小限制以及瀏覽器在存cookie的個數也有限制,Session是沒有大小限制和伺服器的記憶體大小有關。

 

   3、Cookie有安全隱患,通過攔截或本地檔案找得到你的cookie後可以進行攻擊。

 

   4、Session是儲存在伺服器端上會存在一段時間才會消失,如果session過多會增加伺服器的壓力。