iT邦幫忙

2021 iThome 鐵人賽

DAY 8
0
永豐金融APIs

30天全端挑戰!React+Spring Boot+Mongo DB 串接永豐API 打造金融網站系列 第 8

[Day 08] - Spring Boot 實作登入驗證(二)(JWT淺析)

第8天,再撐...22天...

我覺得...有必要繼續深入探討JWT

JWT(JSON Web Token)包含了3大部位:header、payload、signature

  • header →以base64編碼,不加密
    包含:
    1.alg:algorithm(聲明使用的加密演算法)
    2.typ:type(類型,一般統一設為JWT)
    ...其餘不常見的先略過
  • payload →以base64編碼,不加密
    包含:
    1.iss:Issuer(簽發者,通常放你的URI)
    2.sub:subject(主旨,拿來放可用來識別身分的唯一值,ex:帳號)
    3.exp:expiration time(過期時間)
    ...常見的就這3個,也可以自定義新的key:value加入
  • signature → 將 header 跟 payload 兩個部位加在一起,以特定的key+演算法產生的字串

其中header的alg是必填項目,主要功用是拿來讓Server判斷要拿哪種方法解密(有些Server可能設計一個以上不同加密方式)

payload則是主要拿來帶使用者驗證資訊用的,不過因為JWT上不會加密,僅做base64編碼,要注意不能在上面攜帶機敏資料

此外,雖然exp沒規定必帶,但是一般都一定會帶,不然會難以判斷這個token是否該廢止

說到這邊,我在stackoverflow有看到一則有趣的問題,問的是為什麼他的程式產生的JWT token都是一樣的,
看一下這位仁兄產生token的程式是這樣寫:

JWT.create()
.withIssuer("auth0")
.sign(algorithm);

可以發現他的JWT只帶iss,甚至沒有user帳號之類的資訊...
不過token都一樣的最主要的原因還是沒帶exp、iat(issued at time)之類會變動的資訊,
因為一直以相同的內容加密,所以才會一直產生相同的signature...

那麼如果在同個一瞬間,同個User一次產生兩個JWT token,是不是也會相同的signature?
理論上是,不過在一般情況下同個使用者一瞬間要了兩次token的機會不大,
而且就算真的要到了兩個相同的token其實風險也不高,
畢竟有設定過期時間,且可以確定雖然會產生相同token,但不可能跟他人相同(因為必定帶不同的使用者資訊),
不過如果真的無法接受相同token的出現,可以在payload再加一個jti的欄位拿來放亂數,進一步降低產生相同token的機會

最後補充一點,
既然signature是透過將header 跟 payload加密產生的,那為什麼JWT不直接只帶signiture就好了呢?
為什麼還要帶header跟payload?
原因是signature雖然是以header跟payload加密產生的,但是signature本身並不能解密變回header跟payload
signature本身是MAC(訊息認證碼),其功用是拿來驗證訊息有沒有被竄改,
以jwt來講,signature是拿來驗證header 跟 payload有沒有被人亂改的,
因此可以說,header 跟 payload才是主角,是絕不可少的部分

今天就先這樣,之後再想想有什麼要補充的


上一篇
[Day 07] - Spring Boot 實作登入驗證(一)(TOKEN or SESSION?)
下一篇
[Day 09] - Spring Boot 實作登入驗證(三)(JWT實作)
系列文
30天全端挑戰!React+Spring Boot+Mongo DB 串接永豐API 打造金融網站30

尚未有邦友留言

立即登入留言