cookie、session、tooken

一、cookie 的誕生

首先需要知道Http協議的無狀態連接的,即這一次請求和上一次請求是沒有任何關係的,互不認識的,沒有關聯的。

服務端,既不知道上一次請求和這一次請求的關聯,也無法知道哪一個客戶端來請求自己。

這時候,假設有一個客戶請求了登錄介面,然後登錄成功,客戶需要請求首頁,由於http的無狀態連接,不記得咱請求過登錄,並且登錄成功了,在首頁就會看不到登錄成功的用戶資訊。

【登錄介面的用戶資訊無法共享給其他頁面】

1、cookie 技術—客戶端技術

為了解決http 無狀態連接,導致無法共享數據的問題,然後像用戶資訊這種數據,明顯就是好幾個頁面都需要用到的全局資訊,每次請求都到資料庫訪問,會增大資料庫的訪問次數,同時導致減低訪問速度;於是乎,cookie誕生了。

cookie把一些共享的資訊(用戶資訊) 存儲到客戶端的瀏覽器,它在一個域名下是一個全局的。

2、cookie的不足

① cookie 存儲的資訊數量是有限制的,只能存儲少量資訊

② cookie 存儲的資訊在客戶端的瀏覽器里,對於用戶而言就是透明可見的,因為是在自己的瀏覽器上,所以用戶就可以隨意的修改,導致不安全

  • 假設如果真的cookie存儲了用戶的所有資訊,那麼像用戶的密碼這種東西在瀏覽器透明可見,太危險了。

將共享資訊存儲少量(不涉及安全問題的)資訊存儲到客戶端瀏覽器,然後其他的資訊(包括涉及用戶安全的資訊)存儲到服務端,這種將共享資訊(用戶資訊)存儲到服務端的技術就是session技術。

二、session 的誕生

1、session 技術—服務端技術

session 其實也是特殊的cookie,只是資訊存儲的位置是在服務端。Session對象存儲特定用戶會話所需的屬性及配置資訊。這樣,當用戶在應用程式的Web頁之間跳轉時,存儲在Session對象中的變數將不會丟失,而是在整個用戶會話中一直存在下去。

Session對象,保證一個用戶的所有請求操作都應該屬於同一個會話,而另一個用戶的所有請求操作則應該屬於另一個會話。

2、session 原理

是存儲在服務端的一組數據。有些網站是採用session機制來驗證用戶身份的。Session對象主要是用來存儲用戶會話的數據。

SessionID需要存儲在瀏覽器端,通常存儲在 cookie 里。

瀏覽器發送介面請求的時候需要帶著這個sessionID,伺服器端就可以根據這個SessionID,找出當前請求的用戶是誰了。

Session一般都會配置一個過期時間,Session過期之後,用戶就需要重新登錄了。

3、session 的不足

隨著網站的用戶越來越多,Session所需的空間會越來越大,同時單機部署的 Web應用會出現性能瓶頸。[單機 session]
這時候需要進行架構的優化或調整,比如擴展Web 應用節點,在應用伺服器節點之前實現負載均衡。[分散式 session]

負載均衡導致了session的管理出現了問題,難以保證一個用戶的所有請求操作都應該屬於同一個會話,會出現同一個用戶請求應用A,在應用A的伺服器上記錄的用戶資訊[用戶會話Session對象],然後該用戶請求應用B,這時候,用於用戶資訊保存到A服務上,無法共享數據問題。

分散式會話的問題:

解決方式1:在負載均衡時,nginx 可以根據“hash_ip”演算法將同一個 IP 的請求固定到某台伺服器,這樣來自於同一個 ip 的 session 請求總是請求到同樣的伺服器。

解決方式2:對session 進行剝離,把 session 數據徹底從業務伺服器中剝離,單獨存儲在其他外部設備中(redis伺服器–分散式快取中間件)。且外部設備redis還可以採用主備或者主從,甚至集群的模式來達到高可用。、

4、cookie 和 session 的區別和選擇:一般在項目中結合起來時候的

① cookie 數據存放在客戶端上,session 數據放在伺服器上。

② cookie 不安全,session 比較安全

③ session 保存在伺服器上,當訪問增多,會佔用你伺服器的性能,考慮到減輕伺服器性能方面,應當使用 COOKIE。

session認證需要服務端做大量的工作來保證session資訊的一致性以及session的存儲,所以現代的web應用在認證的解決方案上更傾向於客戶端方向,cookie認證是基於客戶端方式的,但是cookie缺點也很明顯。把認證資訊保存在客戶端,關鍵點就是安全的驗證,session是一種方式。

如果只是針對用戶登錄這個應用場景,session 方案並不是唯一的解決方案—基於Token的認證

三、token 的誕生

目前市面上能見到的認證方式分為兩大種——基於Session的和基於Token的。

基於Session的認證,是指在客戶端存儲一個Session Id。認證時,請求攜帶Session Id,並由伺服器從Session數據存儲中找到對應的Session。

基於Token的認證,是指將所有認證相關的資訊在伺服器端編碼成一個Token(token 可以認為就是個長長的字元串),並由伺服器簽名,以確保不被篡改。Token本身是明文的。存在Token里的資訊可以有比如user id、許可權列表、用戶昵稱一類的。這樣伺服器只要拿著token和token的簽名,就可以直接驗證用戶的身份是合法的。在現實當中,基於Token的認證的主要標準是Json Web Token (JWT)

1、token的引入—用戶身份的驗證

Token 是在客戶端頻繁向服務端請求數據,服務端頻繁的去資料庫查詢用戶名和密碼並進行對比,判斷用戶名和密碼正確與否,並作出相應提示,在這樣的背景下,Token 便應運而生。

Token,直接就相當於一個身份證,給 Token 就能確定你的身份。

2、Token 的定義:

Token 是服務端生成的一串字元串,以作客戶端進行請求的一個令牌,當第一次登錄後,伺服器生成一個 Token 便將此 Token 返回給客戶端,以後客戶端只需帶上這個 Token 前來請求數據即可,無需再次帶上用戶名和密碼。

最簡單的 token 組成:uid(用戶唯一的身份標識)、time(當前時間的時間戳)、sign(簽名,由 token 的前幾位 + 鹽以哈希演算法壓縮成一定長的十六進位字元串,可以防止惡意第三方拼接 token 請求伺服器)。

● 當用戶第一次使用帳號密碼成功進行登錄後,伺服器便生成一個Token及Token失效時間並將此返回給客戶端,若成功登陸,以後客戶端只需在有效時間內帶上這個Token前來請求數據即可,無需再次帶上用戶名和密碼

3、使用 Token 的目的:

Token 的目的是為了減輕伺服器的壓力,減少頻繁的查詢資料庫,使伺服器更加健壯。

4、token驗證

  • 每次伺服器驗證客戶端請求裡面帶著的 Token,如果一開始服務端簽發生成的token存儲到資料庫,那麼後邊的查詢驗證會很費時。如果不存儲到資料庫,應該存儲到哪裡呢?

    —存儲到記憶體中(使用redis快取)

四、jwt~ 基於Token的認證的主要標準Json Web Token

由於現在的項目大多前後分離,api 跨域需求又那麼多,api鑒權用jwt(使用jwt 來驗證用戶身份),因為jwt支援跨域使用,且因為有簽名,所以JWT可以防止被篡改。

1、跨域session和cookie失效問題

由於跨域所以發送請求時不會帶上cookie,而session是基於cookie的,所以cookie失效了session也會失效,那麼怎麼解決呢。

2、解決session和cookie失效問題

使用token來模擬session,將token放到請求頭,前端每次請求都帶上token,後端提供一個介面來給前端獲取token。

token是遵從JWT規範的。

3、jwt官網兩大用場景

  • Authorization(授權):這是 jwt 應用最為廣泛的場景。jwt 將數據加密存儲,分發給前端,前端將其放在特定的 header 欄位中(也有放在 params 和 body 中),伺服器收到請求後,解析 jwt 判斷用戶身份,對用戶請求進行限權。
  • Information Exchange(數據交換): jwt 可以通過公鑰和私鑰對資訊進行加密,雙方通訊後,互得數據。

4、jwt 有三部分組成:A.B.C

A:Header,{“type”:”JWT”,”alg”:”HS256″} 固定

B:playload,存放資訊,比如用戶id,過期時間等等,可以被解密,不能存放敏感資訊

C: 簽證,A和B加上秘鑰 加密而成,只要秘鑰不丟失,可以認為是安全的。

jwt 驗證,主要就是驗證C部分 是否合法。

☺ 五、面試聊聊cookie、session、token

這三個是不同維度的東西,沒有什麼可比性。

是存儲在瀏覽器的一小段文本數據;數據大小不超過4kb。Cookie的內容,會隨著http請求一起發送到服務端,即發送網路請求的時候,cookie 會在請求頭裡一起發送給伺服器端。

Session

是存儲在服務端的一組數據。有些網站是採用session機制來驗證用戶身份的。Session對象主要是用來存儲用戶會話的數據。

SessionID需要存儲在瀏覽器端,通常存儲在 cookie 里。

瀏覽器發送介面請求的時候需要帶著這個sessionID,伺服器端就可以根據這個SessionID,找出當前請求的用戶是誰了。

Session一般都會配置一個過期時間,Session過期之後,用戶就需要重新登錄了。

Token

在很多地方都會用到,是一個通用名詞。通常用來表示一小段字元串。Token可以存儲在cookie里,也可以存儲到伺服器的記憶體里,也可以存儲到其他地方。Token 和session、cookie不是一個維度的東西。

目前有一種用戶認證的機制,全名是json web token(jwt)。

參考文章:《Token ,Cookie 和 Session 的區別》//jqiange.github.io/Token-,Cookie和Session的區別/

如果本文對你有幫助的話記得給一樂點個贊哦,感謝!