JSON Web Token (JWT)是一個開放標準(RFC 7519),它定義了一種緊湊的、自包含的方式,用於做爲JSON對象在各方之間安全地傳輸信息。該信息能夠被驗證和信任,由於它是數字簽名的。算法
下列場景中使用JSON Web Token是頗有用的:跨域
Authorization (受權) : 這是使用JWT的最多見場景。一旦用戶登陸,後續每一個請求都將包含JWT,容許用戶訪問該令牌容許的路由、服務和資源。單點登陸是如今普遍使用的JWT的一個特性,由於它的開銷很小,而且能夠輕鬆地跨域使用。
Information Exchange (信息交換) : 對於安全的在各方之間傳輸信息而言,JSON Web Tokens無疑是一種很好的方式。由於JWTs能夠被簽名,例如,用公鑰/私鑰對,你能夠肯定發送人就是它們所說的那我的。另外,因爲簽名是使用頭和有效負載計算的,您還能夠驗證內容沒有被篡改。安全
JSON Web Token由三部分組成,它們之間用圓點(.)鏈接。這三部分分別是:ui
Header Payload Signature
所以,一個典型的JWT看起來是這個樣子的:編碼
xxxxx.yyyyy.zzzzz
Header
header典型的由兩部分組成:token的類型(「JWT」)和算法名稱(好比:HMAC SHA256或者RSA等等)。
例如:
而後,用Base64對這個JSON編碼就獲得JWT的第一部分加密
Payload
JWT的第二部分是payload,它包含聲明(要求)。聲明是關於實體(一般是用戶)和其餘數據的聲明。聲明有三種類型: registered, public 和 private。code
Registered claims : 這裏有一組預約義的聲明,它們不是強制的,可是推薦。好比:iss (issuer), exp (expiration time), sub (subject), aud (audience)等。
Public claims : 能夠隨意定義。
Private claims : 用於在贊成使用它們的各方之間共享信息,而且不是註冊的或公開的聲明。orm
對payload進行Base64編碼就獲得JWT的第二部分jwt
注意,不要在JWT的payload或header中放置敏感信息,除非它們是加密的。
Signature
爲了獲得簽名部分,你必須有編碼過的header、編碼過的payload、一個祕鑰,簽名算法是header中指定的那個,然對它們簽名便可。
例如:對象
HMACSHA256(base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
簽名是用於驗證消息在傳遞過程當中有沒有被更改,而且,對於使用私鑰簽名的token,它還能夠驗證JWT的發送方是否爲它所稱的發送方。
典型模塊以下:
// Header { "alg": "HS256", "typ": "JWT" } // Payload { // reserved claims "sub": "1234567890", "name": "John Doe", "iat": "1516239022" } // $Signature HS256(Base64(Header) + "." + Base64(Payload), "自定義密鑰kyey" ) // JWT JWT = Base64(Header) + "." + Base64(Payload) + "." + $Signature
public static String createJWT(Object subject, long ttlMillis) { //設置簽名算法爲HS256 SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256; long nowMillis = System.currentTimeMillis(); Date now = new Date(nowMillis); JwtBuilder builder = Jwts.builder().setId("jwt").setIssuedAt(now).setSubject(JSONObject.toJSONString(subject)).signWith(signatureAlgorithm, secretKey); //設置過時時間 if (ttlMillis >= 0L) { long expMillis = nowMillis + ttlMillis; Date exp = new Date(expMillis); builder.setExpiration(exp); } //生成jwt return builder.compact(); }
具體compact()方法即根據傳入的參數進行處理 最終獲得jwt的字符串
eyJhbGci**I1NiJ9.eyJqdGkiOiJqd3QiL**DY2NTMxOH0.x9fNW**2fe4ht