基於JWT實現的API網關

git倉庫地址git

1 身份驗證

1.1 傳統的身份驗證

HTTP是一種無狀態的協議,服務器接收一個來自客戶端的request,處理完之後返回一個response。可是這個過程當中,服務器幾乎沒有什麼信息能夠用來判斷是哪一個客戶端(用戶)發來的request。此時若是用戶使用帳戶和密碼登陸,下回再發送請求時,還得再登陸一遍。算法

1.1.1 方案一(cookie)

當用戶登陸成功後,咱們直接把用戶信息保存到cookie中,此後客戶端的每一次請求都會帶上這個cookie。tomcat

缺點:用戶信息都保存在cookie中,容易被cokkie劫持安全

1.1.2 方案二(session)

當用戶登陸成功後,咱們在服務端建立一個session對象,session會生成全局惟一標識符(JSESSIONID),把登陸後的用戶信息都保存在這個session對象中。而後服務端只要把JSESSIONID設置到cookie,此後客戶端的每一次請求都會帶上這個JSESSIONID。服務器

缺點:系統一旦斷電或重啓,全部的會話數據都會丟失。特別是後臺部署新版本,每次重啓tomcat,用戶都須要從新登陸。cookie

1.2 基於TOKEN的身份驗證

使用基於Token的身份驗證流程以下:session

基於Token的認證,除了能避免傳統身份驗證的問題外,還有許多額外的優勢:分佈式

  1. 無狀態:因爲Token已經包含了用戶的全部信息,因此無需再存儲Session
  2. 解耦:無需被綁定在一個特定的驗證方案。做爲獨立的會話系統,利於實現分佈式
  3. 基於標準:JWT做爲Token的標準已經被普遍地接受。主流語言都有相應支持JWT標準的工具包

1.3 JWT

1.3.1 JWT的主要使用場景

  • 身份驗證

一旦用戶完成了登陸,在接下來的每一個請求中都會包含JWT,能夠用來驗證用戶身份以及對路由,服務和資源的訪問權限進行驗證。目前的單點登陸(SSO)比較普遍地使用了該技術。工具

  • 信息交換

在通訊的雙方之間使用JWT對數據進行編碼是一種很是安全的方式,因爲它的信息是通過簽名的,因此能夠確保發送者發送的信息是沒有通過僞造的。編碼

1.3.2 JWT的結構

JWT包含了使用 . 分隔的三部分:頭部(Header)、載荷(Payload)與簽名(Signature)

其結構看起來是這樣的:

eyJhbGciOiJIUzI1NiJ9.eyJleHAiOjE0OTI3NTgxNDksInN1YiI6IkpXVFRva2VuIiwiYXVkIjoia2xkIiwiaXNzIjo.8izVDNnjr8qA-3twii6O0U3FCt0-tdtNHG6eT3LMiBY

Header

在header中一般包含了兩部分:token類型和採用的加密算法:

{
      "typ" : "JWT",
      "alg" : "HS256"
}

Payload

Payload部分包含了一些跟這個token有關的重要信息。經常使用的有:

  • iss:The issuer of the token,token發行人 
  • exp:Expiration Time,過時時間戳
  • sub:The subject of the token,面向的用戶
  • aud:to whom the token is intended to be sent,接收方
  • iat:簽發時間

Payload示例:

{exp=1492771410, sub=org-gateway, aud=kld, iss=dahai, jti=v1, iat=1492767810}

Signature

簽名主要用於驗證token是否有效,是否被篡改。簽名時可使用加密算法進行簽名,例如但願使用HMACSHA256算法進行簽名:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret) 

1.3.3 JWT的安全設置

JWT字符串設置到Cookie時必須使用HttpOnly屬性來防止Cookie被JavaScript讀取,從而避免跨站腳本攻擊(XSS攻擊)。

 

 參考

  • jwt.io
  • 基於Token的認證和基於聲明的標識
  • JSON Web Token (JWT) 簡介
  • 八幅漫畫理解使用JSON Web Token設計單點登陸系統
  • jpadilla/pyjwt
相關文章
相關標籤/搜索