iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 21
0
Modern Web

Golang - 從打造一個 API 開始學起系列 第 21

[Day21] 解析 jwt (一)

本文同步發表於: Sponge Records

本文將會介紹 JWT (JSON Web Token) 的組成與用途

jwt 使用場景

  • 使用者可以使用 jwt 與伺服器端進行認證,因此也能在 sso 的場景下使用
  • 存放可公開且具識別性的會員資料(會員id)來取代掉由伺服器端來存放資料

jwt 的組成

JWT 的由三個部分所組成,分別為 Header 、Payload 、Signature,彼此透過 . 來相連,組成一串完整的 jwt

  • Header

裡面包含聲明類型與加密方法,用來讓解密端能透過以下方法解析 Payload

{
  'typ': 'JWT', //聲明類型
  'alg': 'HS256' //加密的方法
}

然後透過 base64 編碼後產生 Header

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
  • Payload
    這裡存放要傳遞的內容,在定義上有三種內容聲明
  1. Reserved

這些為保留字,為 jwt 標準預設好的欄位,建議使用但不會強制一定要宣告這些內容

iss (Issuer) - jwt簽發者
sub (Subject) - jwt所面向的用戶
aud (Audience) - 接收jwt的一方
exp (Expiration Time) - jwt的過期時間,這個過期時間必須要大於簽發時間
nbf (Not Before) - 定義在什麼時間之前,該jwt都是不可用的
iat (Issued At) - jwt的簽發時間
jti (JWT ID) - jwt的唯一身份標識,主要用來作為一次性token,從而迴避重放攻擊
  1. Public
    一樣為保留字,一般都會以 Private 取代,存放一些大部分情景共用的內容,如姓名、生日,如果要使用這些共用保留字需宣告命名空間,可見 jwt 聲明註冊表

  2. Private
    為自定義的聲明,可以在裡面加入想要存放的資訊,如會員 id 或會員姓名

{
    "memberId": "a01",
    "memberName": "sponge"
}

然後透過 base64 編碼後產生 Private

eyJtZW1iZXJJZCI6ImEwMSIsIm1lbWJlck5hbWUiOiJzcG9uZ2UifQ
  • Signature
    簽名,要是要驗證 Payload 與 Private 內的資訊是否有被修改過,由於存放內容的 Private 實際上是沒有被加密的,透過 base64 解碼就可解析,其他資料透過 base64 編碼後亦有可能偽造資訊

其由三個部分組成

  1. Payload
  2. Private
  3. secret

secret 為金鑰,透過此金鑰來將 base64 編碼過後的 Payload + "." + Private 做雜湊

HMACSHA256("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9" + "." + "eyJtZW1iZXJJZCI6ImEwMSIsIm1lbWJlck5hbWUiOiJzcG9uZ2UifQ", "secret")

然後透過 base64 編碼後產生 Signature

mKpt05h8r24IuXy_h6W523df3co6OcWEkFPRrrdyDw0

jwt

將以上三個部分加在一起,就獲得了一個完整的 jwt,可以透過 Signature 來驗證資料是否被修改,需要提醒的是,記得不要在 Private 內存放機敏資料, Private 是可以被解碼的, Signature 只能夠幫助你確認資料是否有被修改不能幫你的資料加密

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJtZW1iZXJJZCI6ImEwMSIsIm1lbWJlck5hbWUiOiJzcG9uZ2UifQ.mKpt05h8r24IuXy_h6W523df3co6OcWEkFPRrrdyDw0

參考資料

  1. Auth0-Docs
  2. JWT線上驗證網站

下回預告

下回將會繼續介紹 jwt,單獨講解在 api 中運用到的 jwt 是如何實現驗證與加密的


上一篇
[Day20] 儲存圖表資料並提供使用的 api (四)
下一篇
[Day22] 解析 jwt (二)
系列文
Golang - 從打造一個 API 開始學起30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言