咱們都知道 HTTP 是無狀態(stateless)的協議:HTTP 對於事務處理沒有記憶能力,不對請求和響應之間的通訊狀態進行保存。 使用 HTTP 協議,每當有新的請求發送時,就會有對應的新響應產生。協議自己並不保留以前一切的請求或響應報文的信息。這是爲了更快地處理大量事務,確保協議的可伸縮性,而特地把 HTTP 協議設計成如此簡單的。html
但是,隨着 Web 的發展,早期這種無狀態的特性卻帶來了不少不方便性,好比說用戶登陸新浪微博,在登陸頁輸入用戶名、密碼以後進入首頁,可是因爲 HTTP 是無狀態的,HTTP 並不知道上一次的 HTTP 請求是否經過了驗證,更沒法得知當前用戶的具體信息。前端
最簡單的解決方案就是在全部的請求裏面都帶上用戶名和密碼,這樣雖然可行,可是大大加劇了服務器的負擔(對於每一個 request 都須要到數據庫驗證),並且用戶也要每進入一個頁面輸入一次密碼,毫無用戶體驗可言。web
爲此,引入了各類身份認證機制,這裏說一下 Cookie-Session 和 Jwt 機制。算法
Cookie 是由 HTTP 服務器設置的,保存在瀏覽器中的小型文本文件,其內容爲一系列的鍵值對。在 Chrome 中,經過開發者工具 -> Application -> Cookies 可查看 數據庫
這裏簡單介紹一下一些字段意思:Expires:Cookie 的過時時間,默認過時時間爲用戶關閉瀏覽器時。json
HttpOnly:指示瀏覽器不要在除了 HTTP(或者 HTTPS)請求以外暴露 Cookie。經過 JavaScript 腳本沒法訪問到 Cookie,能有效防止 XSS 攻擊後端
Secure:設置 Cookie 的 Secure 屬性爲 true
時,意味着 Cookie 通訊只限於加密傳輸,指示瀏覽器僅僅在經過安全/加密鏈接才能使用 Cookie。也就是說 Cookie 只有在 HTTPS 協議下才能上傳到服務器,而 HTTP 協議下是沒法上傳的。跨域
Set-Cookie
字段,值爲要設置的的CookieSet-Cookie
字段,就會將該字段的值保存在內存或者是硬盤中。Cookie
中。Cookie
字段,就知道了已經處理過這個用戶的請求了。相對於保存在瀏覽器中的 Cookie,Session 是存儲在服務器端的,避免了在客戶端中儲存敏感數據。而且存取方式不一樣,Cookie 只能保存 ASCII 字符串,例如須要存取 Unicode 字符或者二進制數據,須要先進行編碼。而Session中可以存取任何類型的數據。Session 通常配合 Cookie 使用,也就是接下來要說到的 Cookie-Session 機制。瀏覽器
Set-Cookie
字段,將 Cookie 保存起來JWT(JSON Web Token) 是由 RFC7519 定義的,是一個在雙方之間安全的傳達一組信息的 JSON 對象。安全
JWT 由三個部分組成:header、payload、signature 每一個部分中間使用 .
來分隔,其中,header 和 payload 使用 Base64URL 進行編碼:
base64UrlEncode(header).base64UrlEncode(payload).signature
複製代碼
header 部分是一個 JSON 對象,用來描述 JWT 的元數據:
{
"typ": "JWT", // 表示對象是一個 JWT
"alg": "HS256" // 表示使用哪一種 Hash 算法來建立簽名,這裏是 HMAC-SHA256
}
複製代碼
payload 部分也是一個 JSON 對象,實際須要傳遞的數據被存放在這裏。咱們除了使用官方提供的七個字段以外,也可使用自定義的私有字段。
{
"sub": "title",
"name": "Yeoman"
}
複製代碼
JWT 默認是不加密的,任何人均可以讀到,因此不要把祕密信息放在這個部分。
signature 是對前兩個部分的簽名,防止數據被篡改。
data = base64urlEncode( header ) + "." + base64urlEncode( payload );
signature = Hash( data, secret );
複製代碼
使用 Base64URL 編碼的 header 和 payload 中間用 .
隔開,再使用 header 中指定的 Hash 算法,加上密鑰對這個字符串進行 Hash 獲得 signature
Authorization
位,這樣相比放在 Cookie 中能夠跨域。Authorization: Bearer <token>
複製代碼
這裏再次複習一下相關知識: