Server 端的認證方案——擁抱 Json Web Token(一)

What is Json Web Token

根據(jù)官網(wǎng)的定義,JWT 是一套開放的標準(RFC 7519),它定義了一套簡潔的(compact)、自包含的(self-contained)方案,來讓我們安全地在客戶端和服務器之間傳遞 JSON 格式的信息。

Advantages

  • 體積小,因而傳輸速度快
  • 傳輸方式多樣,可以通過 URL/POST 參數(shù)/HTTP 頭部 等方式傳輸
  • 嚴謹?shù)慕Y構化。它自身(在 payload 中)就包含了所有與用戶相關的驗證消息,如用戶可訪問路由、訪問有效期等信息,服務器無需再去連接數(shù)據(jù)庫驗證信息的有效性,并且 payload 支持為你的應用而定制化
  • 支持跨域驗證,多應用于單點登錄。

單點登錄(Single Sign On):在多個應用系統(tǒng)中,用戶只需登陸一次,就可以訪問所有相互信任的應用。

WHY JWT

除了上面說到的優(yōu)點之外,相比傳統(tǒng)的服務端驗證, JWT 還有以下優(yōu)點。

  • 充分依賴無狀態(tài) API ,契合 RESTful 設計原則
  • 易于實現(xiàn) CDN,將靜態(tài)資源分布式管理
  • 驗證解耦,無需使用特定的身份驗證方案, token 可以在任何地方生成
  • 比 cookie 更支持原生移動端應用
  1. 關于狀態(tài)
    首先我們先看一下,什么是狀態(tài),什么是有狀態(tài)與無狀態(tài)。

狀態(tài):請求的狀態(tài)是 client 與 server 交互過程中,保存下來的相關信息,客戶端的保存在 page/request/session/application 或者全局作用域中,而 server 的一般存在 session 中。

有狀態(tài) API:server 保存了 client 的請求狀態(tài), server 會通過 client 傳遞的 sessionID 在其 session 作用域內(nèi)找到之前交互的信息并應答。

無狀態(tài) API:無狀態(tài)是 RESTful 架構設計的一個非常主要的原則。無狀態(tài) API 的每一個請求都是獨立的,它要求由客戶端保存所有需要的認證信息,每次發(fā)請求都要帶上自己的狀態(tài),以 url 的形式提交包含了 cookies 等狀態(tài)的數(shù)據(jù)。

JWT 就很好地體現(xiàn)了無狀態(tài)原則。用戶登陸之后,服務器會返回給他一個 token,由他保存在本地,在這之后的對服務器的訪問都要帶上這串 JWT ,來獲得訪問服務器相關路由、服務及資源的權限。比如單點登錄就比較多地使用了 JWT,因為它的體積小,并且簡單處理(使用 HTTP 頭帶上 Bearer 屬性 + token )就可以支持跨域操作。

  1. 分布式管理
    在傳統(tǒng)的 session 驗證中,服務端必須保存 session ID,用于與用戶傳過來的 cookie 驗證。而在一開始保存 session ID 時, 只會保存在一臺服務器上,所以只能由一個 server 應答,就算其他服務器有空閑也無法應答,因此也利用不到分布式服務器的優(yōu)點。
    而 JWT 依賴的是在客戶端本地保存驗證信息,不需要利用服務器保存的信息來驗證,所以任意一臺服務器都可以應答,服務器的資源也被較好地利用。

  2. 驗證解耦
    只要擁有生成 token 所需的驗證信息,在何處都可以調(diào)用 token 生成接口,無需繁瑣的耦合的驗證操作,可謂是一次生成,永久使用。

  3. 對原生應用的支持(我對移動端開發(fā)不夠深入,這點不是很清楚)
    原生的移動應用對 cookie 與 session 的支持不夠好,而對 token 的方式支持較好。

除此之外,JWT 的可靠的結構化的標準,也是我們選擇它的一大原因。特別是使用 nodejs 開發(fā)時,嗯,node 大法好!

client 使用 JWT 與 server 交互的過程

image

首先,擁有某網(wǎng)站賬號的某 client 使用自己的賬號密碼發(fā)送 post 請求 login,由于這是首次接觸,server 會校驗賬號與密碼是否合法,如果一致,則根據(jù)密鑰生成一個 token 并返回,client 收到這個 token 并保存在本地的 localStorage。在這之后,需要訪問一個受保護的路由或資源時,而只要附加上你保存在本地的 token(通常使用 Bearer 屬性放在 Header 的 Authorization 屬性中),server 會檢查這個 token 是否仍有效,以及其中的校驗信息是否正確,再做出相應的響應。

JWT 由三部分組成:Header/Payload/Signature

// Header
{
  "alg": "HS256",
  "type": "JWT"
}

// Payload
{
  // reserved claims
  "iss": "a.com",
  "exp": "1d",
  // public claims
  "http://a.com": true,
  // private claims
  "company": "A",
  "awesome": true
}

// $Signature
HS256(Base64(Header) + "." + Base64(Payload), secretKey)


JWT = {Base64(Header), Base64(Payload), $Signature}

第一部分是 Header。首先聲明一個 JSON 對象,對象里有一個 type 屬性,值為 JWT ,以及 alg 屬性,值為 HS256,表明最終使用的加密算法是 HS256。

第二部分是 Payload Claim。這一部分被定義為實體的狀態(tài),就像 token 自身附加元數(shù)據(jù)一樣,claim 包含我們想要傳輸?shù)男畔?,以及用于服務器驗證的信息,一般有 reserved/public/private 三類。

第三部分是 Signature。它由前面在 Header 指定的算法 HS256 加密兩個參數(shù)構成,第一個參數(shù)是經(jīng)過編碼的 Header 與經(jīng)過編碼的 Payload 通過 . 連接之后的字符串,第二個參數(shù)是生成的密鑰,會由服務器保存。每次服務器接收到 token 之后,也是先解密出用于驗證的用戶信息以及密鑰,再與自己保存的密鑰對比是否相同,以此來驗證用戶的身份。

寫完這么一大篇真是好累…還想繼續(xù)深挖一下 JWT 具體的應用、服務端如何驗證、JWT 使用 cookie 存儲好還是 HTML5 Web Storage 好的,剩下的只能留在下回分解啦。。

感謝以下參考文章:
Json Web Token Introduction
使用Json Web Token設計Passport系統(tǒng)
深入RESTful無狀態(tài)原則

最后編輯于
?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容