第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才是主角,是絕不可少的部分
今天就先這樣,之後再想想有什麼要補充的