使用go進行 JWT 驗證

對於使用負載均衡的服務器來講,使用 JWT(JSON WEB TOKEN) 是一個更優的選擇,session受到單臺服務器的限制,一個用戶登陸事後就只能分配到
這一臺服務器上,這和負載均衡的初衷不一致啊,而 jwt 就解決了這類的痛點git

使用 JWT 的場景

  • 身份驗證 用戶在登陸事後服務器會用 jwt 返回用戶可訪問的資源,好比權限什麼的
  • 傳遞信息 經過 jwt 的headersignature能夠保證payload沒有被篡改,保證信息的安全

JWT 的結構

JWT 是由header,payload,signature三部分組成的,我們先用例子說話github

  • header
{
  "alg": "HS256",
  "typ": "JWT"
}
// base64編碼的字符串`eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9`

這裏規定了加密算法,hash256算法

  • payload
{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}
// base64編碼的字符串`eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9`
這裏的內容沒有強制要求,由於 paylaod 就是爲了承載內容而存在的,不過想用規範的話也能夠參考下面的
* iss: jwt簽發者
* sub: jwt所面向的用戶
* aud: 接收jwt的一方
* exp: jwt的過時時間,這個過時時間必需要大於簽發時間
* nbf: 定義在什麼時間以前,該jwt都是不可用的.
* iat: jwt的簽發時間
* jti: jwt的惟一身份標識,主要用來做爲一次性token,從而回避重放攻擊。
  • signature

是用 header + payload + secret組合起來加密的,公式是:json

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

這裏 secret就是本身定義的一個隨機字符串,這一個過程只能發生在 server 端,會隨機生成一個 hash 值安全

這樣組合起來以後就是一個完整的 jwt 了:服務器

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.4c9540f793ab33b13670169bdf444c1eb1c37047f18e861981e14e34587b1e04

這裏有一個用 go 加密和驗證 jwt 的 demosession

總結

選擇 jwt 最大的理由:負載均衡

  1. 內容有公鑰私鑰,能夠保證內容的合法性
  2. token 中能夠包含不少信息

不過 jwt 不保證的安全問題:編碼

  1. 由於header,paylaod是 base64編碼,至關於明文可見的,所以不能在payload中放入敏感信息
  2. 並不能保證數據傳輸時會不會被盜用,這一點和 sessionID 同樣,所以不要迷信它有多高的安全性..

爲了安全仍是要上 https加密

相關推薦:
jwt.io

博客原文

相關文章
相關標籤/搜索