cookie,session,token的區別和作用


本文的參考:https://zhuanlan.zhihu.com/p/164696755

1.cookie,session,token的出現的背景

很久很久以前,Web 基本上就是文檔的瀏覽而已, 既然是瀏覽,作為服務器, 不需要記錄誰在某一段時間里都瀏覽了什么文檔,每次請求都是一個新的HTTP協議, 就是請求加響應, 尤其是我不用記住是誰剛剛發了HTTP請求, 每個請求對我來說都是全新的。這段時間很嗨皮

但是隨着交互式Web應用的興起,像在線購物網站,需要登錄的網站等等,馬上就面臨一個問題,那就是要管理會話,必須記住哪些人登錄系統, 哪些人往自己的購物車中放商品, 也就是說我必須把每個人區分開,這就是一個不小的挑戰,因為HTTP請求是無狀態的,所以想出的辦法就是給大家發一個會話標識(session id), 說白了就是一個隨機的字串,每個人收到的都不一樣, 每次大家向我發起HTTP請求的時候,把這個字符串給一並捎過來, 這樣我就能區分開誰是誰了

所以cookie,session,token在這個背景下就出現的,cookie,session,token出現就是為了解決http請求無狀態和無用戶認證的問題。

2.什么是session

上面我們介紹了cookie,session,token的出現的背景,那么這個時候我們就會有這個問題,這三個到底有什么作用和區別呢。這里我們先來介紹什么是session。

在網上很多關於session的介紹和解釋都是太片面和太官方了。

1.不要混淆 session 和 session 實現

這里我們要講的就是,session 是一個抽象概念,是一種方法,並不是具體的某一個東西。很多協議中都會有Session的概念,比如PPPoE(基於以太網的點對點通訊協議。能實現session這個概率功能的我們都把他們稱為session。那么session這個概率到底是要實現什么功能呢?

開發者為了實現中斷和繼續等操作,將 user agent 和 server 之間一對一的交互,抽象為“會話”,進而衍生出“會話狀態”,也就是 session 的概念

  • session 是另一種記錄服務器和客戶端會話狀態的機制
  • session 是基於 cookie 實現的,session 存儲在服務器端,sessionId 會被存儲到客戶端的cookie 中

通俗點講就是為了保存用戶和服務之間的一種會話狀態的一種概念。這個概念目前在http協議中應用較為廣泛。

2.基於http介紹session概念

session 從字面上講,就是會話。這個就類似於你和一個人交談,你怎么知道當前和你交談的是張三而不是李四呢?對方肯定有某種特征(長相等)表明他就是張三。

session 也是類似的道理,服務器要知道當前發請求給自己的是誰。為了做這種區分,服務器就要給每個客戶端分配不同的“身份標識”,然后客戶端每次向服務器發請求的時候,都帶上這個“身份標識”,服務器就知道這個請求來自於誰了。至於客戶端怎么保存這個“身份標識”,可以有很多種方式,對於瀏覽器客戶端,大家都默認采用 cookie 的方式。

服務器使用session把用戶的信息臨時保存在了服務器上,用戶離開網站后session會被銷毀。這種用戶信息存儲方式相對cookie來說更安全,可是session有一個缺陷:如果web服務器做了負載均衡,那么下一個操作請求到了另一台服務器的時候session會丟失。

  • session 認證流程:
    • 用戶第一次請求服務器的時候,服務器根據用戶提交的相關信息,創建對應的 Session
    • 請求返回時將此 Session 的唯一標識信息 SessionID 返回給瀏覽器
    • 瀏覽器接收到服務器返回的 SessionID 信息后,會將此信息存入到 Cookie 中,同時 Cookie 記錄此 SessionID 屬於哪個域名
    • 當用戶第二次訪問服務器的時候,請求會自動判斷此域名下是否存在 Cookie 信息,如果存在自動將 Cookie 信息也發送給服務端,服務端會從 Cookie 中獲取 SessionID,再根據 SessionID 查找對應的 Session 信息,如果沒有找到說明用戶沒有登錄或者登錄失效,如果找到 Session 證明用戶已經登錄可執行后面操作。

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

 

3.什么是cookie

1.什么是cookie

  • HTTP 是無狀態的協議(對於事務處理沒有記憶能力,每次客戶端和服務端會話完成時,服務端不會保存任何會話信息):每個請求都是完全獨立的,服務端無法確認當前訪問者的身份信息,無法分辨上一次的請求發送者和這一次的發送者是不是同一個人。所以服務器與瀏覽器為了進行會話跟蹤(知道是誰在訪問我),就必須主動的去維護一個狀態,這個狀態用於告知服務端前后兩個請求是否來自同一瀏覽器。而這個狀態需要通過 cookie 或者 session 去實現。
  • cookie 存儲在客戶端: cookie 是服務器發送到用戶瀏覽器並保存在本地的一小塊數據,它會在瀏覽器下次向同一服務器再發起請求時被攜帶並發送到服務器上。
  • cookie 是不可跨域的: 每個 cookie 都會綁定單一的域名,無法在別的域名下獲取使用,一級域名和二級域名之間是允許共享使用的靠的是 domain)

2.cookie的作用

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

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

2.個性化設置(如用戶自定義設置,主題等)

3.瀏覽器行為跟蹤(如跟蹤分析用戶行為等)

3.cookie的現狀

cookie曾一度用於客戶端數據的存儲,因當時並沒有其它合適的存儲辦法而作為唯一的存儲手段,但現在隨着現代瀏覽器開始支持各種各樣的存儲方式,cookie漸漸被淘汰。由於服務器指定cookie后,瀏覽器每次請求都會攜帶cookie數據,會帶來額外的性能開銷(尤其是在移動環境下)。新的瀏覽器API已經允許開發者直接將數據存儲到本地,如使用Web storage API (本地存儲和會話存儲)或IndexdDB。

 

4.什么是token

Acesss Token

  • 訪問資源接口(API)時所需要的資源憑證
  • 簡單 token 的組成: uid(用戶唯一的身份標識)、time(當前時間的時間戳)、sign(簽名,token 的前幾位以哈希算法壓縮成的一定長度的十六進制字符串)
  • 特點:
    • 服務端無狀態化、可擴展性好
    • 支持移動端設備
    • 安全
    • 支持跨程序調用
  • token 的身份驗證流程:

  1. 客戶端使用用戶名跟密碼請求登錄
  2. 服務端收到請求,去驗證用戶名與密碼
  3. 驗證成功后,服務端會簽發一個 token 並把這個 token 發送給客戶端
  4. 客戶端收到 token 以后,會把它存儲起來,比如放在 cookie 里或者 localStorage 里
  5. 客戶端每次向服務端請求資源的時候需要帶着服務端簽發的 token
  6. 服務端收到請求,然后去驗證客戶端請求里面帶着的 token ,如果驗證成功,就向客戶端返回請求的數據
  • 每一次請求都需要攜帶 token,需要把 token 放到 HTTP 的 Header 里
  • 基於 token 的用戶認證是一種服務端無狀態的認證方式,服務端不用存放 token 數據。用解析 token 的計算時間換取 session 的存儲空間,從而減輕服務器的壓力,減少頻繁的查詢數據庫
  • token 完全由應用管理,所以它可以避開同源策略

Refresh Token

  • 另外一種 token——refresh token
  • refresh token 是專用於刷新 access token 的 token。如果沒有 refresh token,也可以刷新 access token,但每次刷新都要用戶輸入登錄用戶名與密碼,會很麻煩。有了 refresh token,可以減少這個麻煩,客戶端直接用 refresh token 去更新 access token,無需用戶進行額外的操作。

  • Access Token 的有效期比較短,當 Acesss Token 由於過期而失效時,使用 Refresh Token 就可以獲取到新的 Token,如果 Refresh Token 也失效了,用戶就只能重新登錄了。
  • Refresh Token 及過期時間是存儲在服務器的數據庫中,只有在申請新的 Acesss Token 時才會驗證,不會對業務接口響應時間造成影響,也不需要向 Session 一樣一直保持在內存中以應對大量的請求。

5.Token和Session的區別

  • Session 是一種記錄服務器和客戶端會話狀態的機制,使服務端有狀態化,可以記錄會話信息。而 Token 是令牌訪問資源接口(API)時所需要的資源憑證。Token 使服務端無狀態化,不會存儲會話信息。
  • Session 和 Token 並不矛盾,作為身份認證 Token 安全性比 Session 好,因為每一個請求都有簽名還能防止監聽以及重放攻擊,而 Session 就必須依賴鏈路層來保障通訊安全了。如果你需要實現有狀態的會話,仍然可以增加 Session 來在服務器端保存一些狀態。
  • 所謂 Session 認證只是簡單的把 User 信息存儲到 Session 里,因為 SessionID 的不可預測性,暫且認為是安全的。而 Token ,如果指的是 OAuth Token 或類似的機制的話,提供的是 認證 和 授權 ,認證是針對用戶,授權是針對 App 。其目的是讓某 App 有權利訪問某用戶的信息。這里的 Token 是唯一的。不可以轉移到其它 App上,也不可以轉到其它用戶上。Session 只提供一種簡單的認證,即只要有此 SessionID ,即認為有此 User 的全部權利。是需要嚴格保密的,這個數據應該只保存在站方,不應該共享給其它網站或者第三方 App。所以簡單來說:如果你的用戶數據可能需要和第三方共享,或者允許第三方調用 API 接口,用 Token 。如果永遠只是自己的網站,自己的 App,用什么就無所謂了。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM