Cookie 和 Session 關係詳解

目錄

什麼是 Cookie 和 Session ?

Cookie和Session的區別

爲什麼需要 Cookie 和 Session,他們有什麼關聯?

如果瀏覽器中禁止了 Cookie,如何保障整個機制的正常運轉。

如何考慮分佈式 Session 問題?

如何解決Cookie跨域請求?Jsonp 跨域的原理是什麼?

 

什麼是 Cookie 和 Session ?

什麼是 Cookie

HTTP Cookie(也叫 Web Cookie或瀏覽器 Cookie)是服務器發送到用戶瀏覽器並保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶併發送到服務器上。通常,它用於告知服務端兩個請求是否來自同一瀏覽器,如保持用戶的登錄狀態。Cookie 使基於無狀態的 HTTP 協議記錄穩定的狀態信息成爲了可能。

Cookie 主要用於以下三個方面:

  • 會話狀態管理(如用戶登錄狀態、購物車、遊戲分數或其它需要記錄的信息)

  • 個性化設置(如用戶自定義設置、主題等)

  • 瀏覽器行爲跟蹤(如跟蹤分析用戶行爲等)

什麼是 Session

Session 代表着服務器和客戶端一次會話的過程。Session 對象存儲特定用戶會話所需的屬性及配置信息。這樣,當用戶在應用程序的 Web 頁之間跳轉時,存儲在 Session 對象中的變量將不會丟失,而是在整個用戶會話中一直存在下去。當客戶端關閉會話,或者 Session 超時失效時會話結束。

 

Cookie和Session的區別

cookie和session的共同之處在於:cookie和session都是用來跟蹤瀏覽器用戶身份的會話方式。

區別在於:

1. 由於HTTP協議是無狀態的協議,所以服務端需要記錄用戶的狀態時,就需要用某種機制來識別具體的用戶,這個機制就是Session,典型的場景比如購物車,當你點擊下單按鈕時,由於HTTP協議無狀態,所以並不知道是哪個用戶操作的,所以服務端要爲特定的用戶創建了特定的Session,用於標識這個用戶,並且跟蹤用戶,這樣才知道購物車裏面有幾本書。這個Session是保存在服務端的,有一個唯一標識。在服務端保存Session的方法很多,內存、數據庫、文件都有。集羣的時候也要考慮Session的轉移,在大型的網站,一般會有專門的Session服務器集羣,用來保存用戶會話,這個時候 Session 信息都是放在內存的,使用一些緩存服務比如Memcached之類的來放 Session。

2. 思考一下服務端如何識別特定的客戶?這個時候Cookie就登場了。每次HTTP請求的時候,客戶端都會發送相應的Cookie信息到服務端。實際上大多數的應用都是用 Cookie 來實現Session跟蹤的,第一次創建Session的時候,服務端會在HTTP協議中告訴客戶端,需要在 Cookie 裏面記錄一個Session ID,以後每次請求把這個會話ID發送到服務器,我就知道你是誰了。有人問,如果客戶端的瀏覽器禁用了 Cookie 怎麼辦?一般這種情況下,會使用一種叫做URL重寫的技術來進行會話跟蹤,即每次HTTP交互,URL後面都會被附加上一個諸如 sid=xxxxx 這樣的參數,服務端據此來識別用戶。

3. Cookie其實還可以用在一些方便用戶的場景下,設想你某次登陸過一個網站,下次登錄的時候不想再次輸入賬號了,怎麼辦?這個信息可以寫到Cookie裏面,訪問網站的時候,網站頁面的腳本可以讀取這個信息,就自動幫你把用戶名給填了,能夠方便一下用戶。這也是Cookie名稱的由來,給用戶的一點甜頭。

所以,總結一下:

Session是在服務端保存的一個數據結構,用來跟蹤用戶的狀態,這個數據可以保存在集羣、數據庫、文件中;

Cookie是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息,也是實現Session的一種方式。

因此,如果遇到面試官問你Cookie 和 Session 有什麼不同?我們可以做如下回答

  • 1、作用範圍不同,Cookie 保存在客戶端(瀏覽器),Session 保存在服務器端。

  • 2、存取方式的不同,Cookie 只能保存 ASCII,Session 可以存任意數據類型,一般情況下我們可以在 Session 中保持一些常用變量信息,比如說 UserId 等。

  • 3、有效期不同,Cookie 可設置爲長時間保持,比如我們經常使用的默認登錄功能,Session 一般失效時間較短,客戶端關閉或者 Session 超時都會失效。

  • 4、隱私策略不同,Cookie 存儲在客戶端,比較容易遭到不法獲取,早期有人將用戶的登錄名和密碼存儲在 Cookie 中導致信息被竊取;Session 存儲在服務端,安全性相對 Cookie 要好一些。

  • 5、存儲大小不同, 單個 Cookie 保存的數據不能超過 4K,Session 可存儲數據遠高於 Cookie。

 

爲什麼需要 Cookie 和 Session,他們有什麼關聯?

說起來爲什麼需要 Cookie ,這就需要從瀏覽器開始說起,我們都知道瀏覽器是沒有狀態的(HTTP 協議無狀態),這意味着瀏覽器並不知道是張三還是李四在和服務端打交道。這個時候就需要有一個機制來告訴服務端,本次操作用戶是否登錄,是哪個用戶在執行的操作,那這套機制的實現就需要 Cookie 和 Session 的配合。

那麼 Cookie 和 Session 是如何配合的呢?我畫了一張圖大家可以先了解下。

 

用戶第一次請求服務器的時候,服務器根據用戶提交的相關信息,創建創建對應的 Session ,請求返回時將此 Session 的唯一標識信息 SessionID 返回給瀏覽器,瀏覽器接收到服務器返回的 SessionID 信息後,會將此信息存入到 Cookie 中,同時 Cookie 記錄此 SessionID 屬於哪個域名。

當用戶第二次訪問服務器的時候,請求會自動判斷此域名下是否存在 Cookie 信息,如果存在自動將 Cookie 信息也發送給服務端,服務端會從 Cookie 中獲取 SessionID,再根據 SessionID 查找對應的 Session 信息,如果沒有找到說明用戶沒有登錄或者登錄失效,如果找到 Session 證明用戶已經登錄可執行後面操作。

根據以上流程可知,SessionID 是連接 Cookie 和 Session 的一道橋樑,大部分系統也是根據此原理來驗證用戶登錄狀態。

 

 

既然服務端是根據 Cookie 中的信息判斷用戶是否登錄,那麼:

如果瀏覽器中禁止了 Cookie,如何保障整個機制的正常運轉。

第一種方案,每次請求中都攜帶一個 SessionID 的參數,也可以 Post 的方式提交,也可以在請求的地址後面拼接 xxx?SessionID=123456...

第二種方案,Token 機制。Token 機制多用於 App 客戶端和服務器交互的模式,也可以用於 Web 端做用戶狀態管理。

Token 的意思是“令牌”,是服務端生成的一串字符串,作爲客戶端進行請求的一個標識。Token 機制和 Cookie 和 Session 的使用機制比較類似。

當用戶第一次登錄後,服務器根據提交的用戶信息生成一個 Token,響應時將 Token 返回給客戶端,以後客戶端只需帶上這個 Token 前來請求數據即可,無需再次登錄驗證。

 

如何考慮分佈式 Session 問題?

在互聯網公司爲了可以支撐更大的流量,後端往往需要多臺服務器共同來支撐前端用戶請求,那如果用戶在 A 服務器登錄了,第二次請求跑到服務 B 就會出現登錄失效問題。

分佈式 Session 一般會有以下幾種解決方案:

  • Nginx ip_hash 策略,服務端使用 Nginx 代理,每個請求按訪問 IP 的 hash 分配,這樣來自同一 IP 固定訪問一個後臺服務器,避免了在服務器 A 創建 Session,第二次分發到服務器 B 的現象。

  • Session 複製,任何一個服務器上的 Session 發生改變(增刪改),該節點會把這個 Session 的所有內容序列化,然後廣播給所有其它節點。

  • 共享 Session,服務端無狀態話,將用戶的 Session 等信息使用緩存中間件來統一管理,保障分發到每一個服務器的響應結果都一致。

  •  

如何解決Cookie跨域請求?Jsonp 跨域的原理是什麼?

說起跨域請求,必須要了解瀏覽器的同源策略,同源策略/SOP(Same origin policy)是一種約定,由 Netscape 公司 1995年引入瀏覽器,它是瀏覽器最核心也最基本的安全功能,如果缺少了同源策略,瀏覽器很容易受到 XSS、CSFR 等攻擊。所謂同源是指"協議+域名+端口"三者相同,即便兩個不同的域名指向同一個 ip 地址,也非同源。

解決跨域請求的常用方法是:

  • 通過代理來避免,比如使用 Nginx 在後端轉發請求,避免了前端出現跨域的問題。

  • 通過 Jsonp 跨域

  • 其它跨域解決方案

重點談一下 Jsonp 跨域原理。瀏覽器的同源策略把跨域請求都禁止了,但是頁面中的 <script><img><iframe>標籤是例外,不受同源策略限制。Jsonp 就是利用 <script>標籤跨域特性進行跨域數據訪問。

JSONP 的理念就是,與服務端約定好一個回調函數名,服務端接收到請求後,將返回一段 Javascript,在這段 Javascript 代碼中調用了約定好的回調函數,並且將數據作爲參數進行傳遞。當網頁接收到這段 Javascript 代碼後,就會執行這個回調函數,這時數據已經成功傳輸到客戶端了。

JSONP 的缺點是:它只支持 GET 請求,而不支持 POST 請求等其他類型的 HTTP 請求。

 

原文微信鏈接:https://mp.weixin.qq.com/s?__biz=MzU3NzczMTAzMg==&mid=2247484088&idx=1&sn=dfd3fc2b2a314ae28c2d2cb189c209e0&chksm=fd01620fca76eb19a203087ebf105fa67d707dba438922f78f0c3f7bad6edf949e0e608cbdb8&scene=27&ascene=0&devicetype=android-28&version=2700043a&nettype=WIFI&abtest_cookie=BAABAAoACwASABMABgAjlx4AwJkeANyZHgD3mR4AAJoeAAOaHgAAAA%3D%3D&lang=zh_CN&pass_ticket=Ciu5GUChx8P7YuVe87eJG%2B24mukRzWjrM4XNgwy%2Fs84L5V%2B05GPSUo%2B7FwsHFKpQ&wx_header=1

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章