狀態管理小能手:Cookie 和 Session
一、引言
大家好,我是小?,一個漂泊江湖多年的 985 非科班程序員,曾混跡于國企、互聯網大廠和創業公司的后臺開發攻城獅。
假期搶票的尷尬事件
最近小?在搶出行的高鐵票時,發生了一件尷尬的事情。
這不是臨近中秋和國慶假期了嘛,按以往經驗,搶票應該比較難。于是我通過渠道找了一牛子哥,幫忙搶票,搶票時間在第二天早上 9 點。
好巧不巧,第二天 8點多的時候正好打開了手機,就想著上 12306 去看看票。
輸手機號,拿驗證碼,登錄,一氣呵成!
結果,到 9 點多的時候牛子哥給我說搶票失敗了!原因竟然是中途賬號被頂了,而 12306 一個賬號同一時間只能讓一部手機登錄。
啊這?!
我還以為牛子哥用了什么高端渠道,或者是神奇 App,原來...
于是,我就趁此機會復習一下 12306 的登錄機制,便有了這篇文章!
設備限制的底層邏輯
如今,網站或者手機應用限制登錄設備個數已經屢見不鮮了。
不管是限制登錄個數,還是保持登錄狀態,都和網絡交互的 HTTP 協議,以及客戶端和服務端的 Cookie、Session 技術息息相關。
雖然咱每天都在與它們打交道,但你是否真的理解它們的原理和使用方式呢?接下來,讓我們一起來揭開它們的神秘面紗吧!
二、產生背景
我們都知道,HTTP 是一個無狀態協議。
無狀態是指服務端不會跟蹤和記錄請求,即對請求處理沒有記憶能力,這意味著每個請求都是獨立的。
它的優缺點分別是:
- 優點:服務器處理請求時不需要上下文信息,因此應答很快,每一次請求都是“點到為止”,提升了請求處理的效率。
- 缺點:缺少訪問狀態意味著如果后續請求和之前有關聯,比如 APP 登錄功能,就會導致切換 APP 頁面時,就必須重傳請求。
想象一下,每次在手機上切換應用,或者把應用收到后臺就需要我們重新登錄一次,那也太惡心了。
一般應用或者網站都會有這種登錄狀態:
所以,我們對登錄功能的訴求是:
- 登陸 APP 時,需要記住登錄用戶名密碼信息,避免每次都進行用戶名密碼輸入操作。
- 登陸 APP 時,需要記住用戶登陸的狀態,避免每次都進行重復登錄的操作。
除此之外,在一些其它 Web 交互場景下也需要記住狀態,比如:
- 購物車添加商品時,需要標識和跟蹤某個用戶,才能知道購物車里面有幾本書。
于是,兩種用于保持 HTTP 連接狀態的技術應運而生,分別是 Cookie 和 Session。
三、Session:身份的標識符
Session,就像你的身份證一樣,是一種在服務器和客戶端之間傳遞身份信息的方式。
用戶登錄生成 Session 的時序圖如下:
當你登錄一個網站時,服務器會生成一個唯一的 SessionID,并將它存儲在服務器端,然后將這個 ID 發送到你的瀏覽器,通常以 Cookie 的形式。
Postman 請求登錄接口,響應如下:
postman請求登錄接口
這個 SessionID 就像是你的通行證,每當你訪問需要登錄的頁面時,瀏覽器都會將它發送給服務器。
服務器通過這個 ID 來識別你,就像保安看到你的身份證一樣。
四、Cookie:保持記憶
Cookie 是一個小小的文本文件,它被存儲在你的瀏覽器中。
正如 Cookie 本身的含義,它就像一個小甜點,作用是讓服務器能夠在不同的 HTTP 請求之間"記住"你。
當你登錄一個網站時,服務器已經將一些信息存儲在 Cookie 中,比如你的用戶名或一些用戶首選項。
然后,每當你再次訪問這個網站時,瀏覽器都會將這些信息發送給服務器,這樣服務器就能夠"認識"你,而不需要你重新登錄。
用戶通過 Cookie 與應用交互的時序圖如下:
通過將 SessionId 放在緩存里,每次用戶交互時只要帶上 Cookie,應用層就可以解析出對應的 SessionId,驗證用戶的身份,獲取用戶信息。
Postman 交互如下:
postman調用業務接口
有時,為了信息隱私,我們可以在瀏覽器設置不記錄 Cookie。
但是,這樣我們每次在頁面交互時都需要重新登錄,體驗就會比較差。
五、Session與 Cookie 的關系
PS:這個是 Web 和后臺開發面試的常考題,趕快拿小本本記下來 ??
聯系
如上所示,Session 和 Cookie 之間有著密切的關系。
通常,服務器會將 SessionId 存儲在一個 Cookie 中,并將它發送給你的瀏覽器或其它設備。
然后,瀏覽器在每次請求中都會自動包含這個 Cookie,這樣服務器就能夠識別你的 SessionId,從而知道你是誰。
所以,你可以將 Session 看作是服務器的身份驗證標識,而 Cookie 則是瀏覽器/用戶設備的記憶工具,用于保存一些有關你的信息。
區別
那么,Session和 Cookie 有什么不同呢?
(1) 訪問機制
Cookie 通過檢查客戶端的用戶“通行證”來確定用戶身份,Session 檢查服務器的“客戶檔案表”來確認用戶狀態。
(2) 安全程度
不法分子可能會分析存放在本地的 Cookie 進行 Cookie 欺騙,而 Session 是有人登陸或者啟動某個會話時才會產生,且 Session 是加密和定時失效的,所以 Session 安全系數更高。
(3) 會話機制
簡單來說,Session 的隱私度更高,因為它的數據存儲在服務器端,用戶無法直接修改。
而 Cookie 存儲在用戶的瀏覽器中,用戶可以看到和修改它們的內容,所以不適合存儲敏感信息。
使用場景方面,Session 通常用于存儲用戶的登錄狀態和其他敏感信息,而 Cookie 可以用于存儲一些用戶首選項或跟蹤用戶的行為,比如購物車中的商品。
六、小結
登錄設備限制
明白了 Cookie 和 Session 的底層邏輯,限制設備的登錄個數是不是就很簡單了。
我們只需要在登錄時,根據賬號密碼,記錄一下當前設備已有的 Session 數量,就可以控制登錄設備的個數了。
如果要根據客戶端類型去限制,比如可以允許電腦和手機同時在線,我們就可以在登錄時記錄用戶的設備類型,以此控制每一種設備類型只能有一個 Session。
更進一步,如果基于安全考慮,我們可以在登錄時記錄用戶的設備 Id。
比如手機在通話框輸入 *#06#,就可以拿到手機的唯一標識碼 IMEA
每次用戶用新設備登錄時,需要先通過手機號或人臉驗證,再記錄設備的 IMEA 碼,以此來保證登錄設備的可靠性。
結語
Session 與 Cookie 是構建現代網站的重要組成部分。它們為用戶提供了方便的登錄和個性化體驗,同時也保障了用戶的隱私和安全。
通過深入理解這兩者的原理和用法,我們可以更好地構建安全、高效的網絡應用程序。
希望這篇文章讓你對 Session與 Cookie 有了更清晰的認識,如果大家有任何問題或想要了解更多,請隨時留言。