瞭解登陸中的JWT

1.JSON Web Token是什麼

    JSON Web Token (JWT)是一個開放標準(RFC 7519),它定義了一種緊湊的、自包含的方式,用於做爲JSON對象在各方之間安全地傳輸信息。該信息能夠被驗證和信任,由於它是數字簽名的。算法

2.JSON Web Token有什麼用

下列場景中使用JSON Web Token是頗有用的:跨域

Authorization (受權) : 這是使用JWT的最多見場景。一旦用戶登陸,後續每一個請求都將包含JWT,容許用戶訪問該令牌容許的路由、服務和資源。單點登陸是如今普遍使用的JWT的一個特性,由於它的開銷很小,而且能夠輕鬆地跨域使用。
Information Exchange (信息交換) : 對於安全的在各方之間傳輸信息而言,JSON Web Tokens無疑是一種很好的方式。由於JWTs能夠被簽名,例如,用公鑰/私鑰對,你能夠肯定發送人就是它們所說的那我的。另外,因爲簽名是使用頭和有效負載計算的,您還能夠驗證內容沒有被篡改。安全

3.JSON Web Token是什麼樣的

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

4.具體實現

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
相關文章
相關標籤/搜索