簡潔安全的資料傳輸方式— JSON Web Token(JWT)

George Chang
origino
Published in
3 min readAug 14, 2017

JWT 是一個讓兩個Web應用程式能夠安全、確保資料不會被竄改的Token。

p.s. token個人喜歡翻譯為”標記”,中國那邊有些會翻為”令牌”,也不錯。

我們會利用JWT來作使用者驗證與傳輸資料,常見的用法是建立一個Authentication server負責使用者認證,當使用者通過認證後變可以發行JWT給使用者,因為JWT包含使用者的資料,因此也可以運用在不同的網域/應用程式(Single Sign On)。

首先我們來看看JWT的格式:

JWT為一組字串,由 . 來連接。

[HEADER].[PAYLOAD].[SIGNATURE]

分為HEADER、PAYLOAD與SIGNATURE三個部分。

HEADER

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

這是HEADER的內容,以JSON表示,標示了token的類型(當然是JWT)與使用的加密演算法,這裡是使用HS256,附上其餘能使用的演算法清單

再轉為base64url的編碼去得出JWT的第一段。

PAYLOAD

用來放必要的資料(通常是用來認證使用者的資料)或額外的資料(metadata)。

例如:

{
"user_id": 007,
"name": "Robin"
}

這裡也有一些標準欄位可以使用。

例如:

{
"iss":"joe", //issuer
"exp":1300819380 //expiration time
}

一樣再轉為base64url的編碼去得出JWT的第二段。

SIGNATURE

我們在header表明使用的加密演算法為HS256,於是SIGNATURE的加密方式便如下:

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

若以Python為範例:

import hmac
import hashlib
import base64
secret = "robinisawsome"
msg = base64.b64encode(header).decode() + "." + base64.b64encode(payload).decode()
dig = hmac.new(secret, msg=msg, digestmod=hashlib.sha256).digest()
signature = base64.b64encode(dig).decode()

因此一個JWT可能會長得像:

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ

而JWT被形容為:

Compact:我比較傾向翻譯為”簡潔的”,因為它很小,所以可以經由URL parameter、POST parameter或者header傳輸,也代表傳輸速度快。

Self-contained:PAYLOAD裡面就應該包含足夠的使用者資料,不需要再花費一次request去取得其他資料。

如上述所介紹的特性(輕量、安全、JSON格式)讓這樣一個token很適合用來驗證來源的可靠性。

Reference:

--

--