jwt判断token是否过期_前端也得搞懂 JWT 这个知识点
什么是 JWT
概念
JSON Web Token(簡稱 JWT)是目前最流行的跨域認證解決方案。
JWT 原理
JWT 組成
JWT 由三部分組成:Header,Payload,Signature 三個部分組成,并且最后由.拼接而成。
Header
Header 部分是一個 JSON 對象,描述 JWT 的元數據,通常是下面的樣子。
{"alg": "HS256",
"typ": "JWT"
}
上面代碼中,alg 屬性表示簽名的算法(algorithm),默認是 HMAC SHA256(寫成 HS256);typ 屬性表示這個令牌(token)的類型(type),JWT 令牌統一寫為 JWT。
最后將上面的 JSON 對象使用 Base64URL 算法轉成字符串。
Payload
Payload 中由 Registered Claim 以及需要通信的數據組成。它也是 JSON 格式,另外這些數據字段也叫 Claim。JWT 規定了7個官方字段如下
iss (issuer):簽發人exp (expiration time):過期時間
sub (subject):主題
aud (audience):受眾
nbf (Not Before):生效時間
iat (Issued At):簽發時間
jti (JWT ID):編號
除了官方的字段外你也可以自定義一些字段,比如 user_id,name 等
Registered Claim 中比較重要的是 "exp" Claim 表示過期時間,在用戶登錄時會設置過期時間,用于后面過期校驗。
const payload = {Signature
Signature 部分是對前兩部分的簽名,防止數據篡改。
首先,需要指定一個密鑰(secret)。這個密鑰只有服務器才知道,不能泄露給用戶。然后,使用 Header 里面指定的簽名算法(默認是 HMAC SHA256),按照下面的公式產生簽名。
// 由 HMACSHA256 算法進行簽名,secret 不能外泄算出簽名以后,把 Header、Payload、Signature 三個部分拼成一個字符串,每個部分之間用"點"(.)分隔,。
JWT 校驗原理
圖片總是更清晰:
通過前面講解的 jwt 生成規則,jwt 前兩部分是對 header 以及 payload 的 base64 編碼。?當服務器收到客戶端的 token 后,解析前兩部分得到 header 以及 payload,并使用 header 中的算法與 服務端本地私有 secret 進行簽名,判斷與 jwt 中攜帶的簽名是否一致。
編碼擴展知識
base64
由于 ASCII 碼稱為了國際標準,所以我們要把其它字符轉成 ASCII 就要用到 base64。
utf-8 -> base64(編碼) -> ASCII
ASCII -> base64(解碼) -> utf-8這樣就可以讓只支持 ASCII 的計算機支持 utf-8 了。
base64 幾個特點 :2進制的;要比源數據多33%;常用于郵件;?= 號的個數是由 /3 的余數來決定的,最多能有 2 個 = 號;
主要用于初步的加密(非明文可見)和安全的網絡傳輸。
UrlEncode
例子:www.baidu.com?a=nihao
上面的例子可以看出 a 的值是你好
如果要把 a 的值換成 “=” 字符呢?這樣嗎:www.baidu.com?a== ,肯定不行啦,“=” 是特殊字符
所以把 “=” UrlEncode后 “%3d”
www.baidu.com?a=%3d
服務器拿到 a 解碼得到 “=”
所以說 url 是限制性編碼
看完這兩個編碼應該明白為什么上面base64.encode這種格式轉換。JWT ?作為一個令牌(token),有些場合可能會放到 URL(比如 www.inode.club/?token=xxx)
JWT 與 Session 對比
有無狀態對比
Session
Session 是一種記錄服務器和客戶端會話狀態的機制,需要在數據庫或者 Redis 中保存用戶信息和token信息,所以它是有狀態的。
JWT 看完了前面的 JWT 結構和 JWT 校驗原理,在后端并不需要存儲數據,直接通過私有密鑰驗證就可以了。
當有這樣的一個需求,一家公司下同時關聯了多個業務,A業務網站,B業務網站,但是現在要求用戶在A網站登陸過,再訪問B網站的時候能夠自動登陸,JWT 就可以很快的實現這個需求,把 JWT 直接存儲在前端,后端只要校驗 JWT 就可以了。
注:這個需求用 session 也是可以實現的,只是會存儲狀態,查詢存儲,沒有 JWT 方便而已。
適用場景對比
郵箱驗證
很多網站在注冊成功后添加了郵箱驗證功能,功能實現:用戶注冊成功后,完善郵箱,服務端會給用戶郵箱發一個鏈接,用戶點開鏈接校驗成功,這個功能使用 JWT 是個不錯的選擇。
// 把郵箱以及用戶id綁定在一起,設置生效時間做那些短期的驗證需求(強烈推薦的場景)
比如在?BFF?層,用 JWT 去驗證傳遞一些數據還是不錯的選擇,可以把有效時間設置的短一些,過期了就需要重新去請求,我這么直接表述你可能還不太懂,舉個現實生活中的例子。
我們上學的時候,有班主任和學科老師這兩個概念,有一天你想請假,你需要先去找班主任開一個請假條,然后請教條你的班主任簽完字之后,你會將請假條交給你的學科課教師,學科教師確認簽字無誤后,把請假條收了,并在請假記錄表中作出了相應記錄。
上面的例子中,“請假申請單”就是JWT中的payload,領導簽字就是base64后的數字簽名,領導是issuer,“學科教師的老王”即為JWT的audience,audience需要驗證班主任簽名是否合法,驗證合法后根據payload中請求的資源給予相應的權限,同時將JWT收回。
放到一些系統集成的應用場景中,例如我前面說的?BFF?中其實 JWT 更適合一次性操作的認證:
服務 B 你好, 服務 A 告訴我,我可以操作 , 這是我的憑證(即 JWT )
在這里,服務 A 負責認證用戶身份(類似于上例班主任批準請假),并頒布一個很短過期時間的JWT給瀏覽器(相當于上例的請假單),瀏覽器(相當于上例請假的我們)在向服務 B 的請求中帶上該 JWT,則服務 B(相當于上例的任課教師)可以通過驗證該 JWT 來判斷用戶是否有權限執行該操作。通過這樣,服務 B 就成為一個安全的無狀態的服務。
個人還是認為 JWT 更適合做一些一次性的安全認證,好多其他場景考慮多了之后又做回了 session,傳統的 cookie-session 機制工作得更好,但是對于一次性的安全認證,頒發一個有效期極短的JWT,即使暴露了危險也很小。上面的郵箱驗證其實也是一次性的安全認證。
跨域認證
因為 JWT 并不使用 Cookie ,所以你可以使用任何域名提供你的 API 服務而不需要擔心跨域資源共享問題(CORS)。JWT 確實是跨域認證的一個解決方案,但是對于跨域場景時要注意一點。?客戶端收到服務器返回的 JWT,可以儲存在 Cookie 里面,也可以儲存在 localStorage。
此后,客戶端每次與服務器通信,都要帶上這個 JWT。你可以把它放在 Cookie 里面自動發送,但是這樣不能跨域,所以更好的做法是放在 HTTP 請求的頭信息Authorization字段里面。
Authorization: Bearer另一種做法是,跨域的時候,JWT 就放在 POST 請求的數據體里面。
跨域知識擴展
跨域這兩個字就像一塊狗皮膏藥一樣黏在每一個開發者身上,無論你在工作上或者面試中無可避免會遇到這個問題。為了應付面試,我們每次都隨便背幾個方案。但是如果突然問你為什么會有跨域這個問題出現??...停頓幾秒,這里只是普及一下,知道的可以忽略掉。
推薦一篇很棒的跨域文章:https://segmentfault.com/a/1190000015597029
登陸驗證
登陸驗證:不需要控制登錄設備數量以及注銷登陸情況,無狀態的 jwt 是一個不錯的選擇。具體實現流程,可以看上文中的校驗原理,校驗原理使用的登陸驗證例子。
當需求中出現控制登陸設備數量,或者可以注銷掉用戶時,可以考慮使用原有的 session 模式,因為針對這種登陸需求,需要進行的狀態存儲對 jwt 添加額外的狀態支持,增加了認證的復雜度,此時選用 session 是一個不錯的選擇。?針對上面的特殊需求,可能也有小伙伴仍喜歡使用 jwt ,補充一下特殊案例
注銷登陸
用戶注銷時候要考慮 token 的過期時間。
- session: 只需要把 user_id 對應的 token 清掉即可 ;
- jwt: 使用 redis,需要維護一張黑名單,用戶注銷時把該 token 加入黑名單,過期時間與 jwt 的過期時間保持一致。
用戶登陸設備控制
session: 使用 sql 類數據庫,維護一個用戶驗證token表,每次登陸重置表中 token 字段,每次請求需要權限接口時,根據 token 查找 user_id(也可以使用 redis 維護 token 數據的存儲)
jwt: 假使使用 sql 類數據庫,維護一個用戶驗證token表,表中添加 token 字段,每次登陸重置 token 字段,每次請求需要權限接口時,根據 jwt 獲取 user_id,根據 user_id 查用戶表獲取 token 判斷 token 是否一致。(也可以使用 redis 維護 token 數據的存儲)
適合做那些事來講的,其實也就是針對JWT的優勢來說的,還有一些辯證性的理解。接下來說說 JWT 的缺點。
JWT 注意事項(缺點)
缺點與優勢都知道了,我想怎么選就看你自己了。
總結
本文對 JWT 進行的一個辯證的講解,優勢和缺點,以及個人認為合適的適用場景,JWT 并不是銀彈,是否采用 JWT,一定要多考慮一下業務場景。希望本文讓小伙伴們對 JWT 認識的更好些。
??愛心三連擊
1.看到這里了就點個在看支持下吧,你的「點贊,在看」是我創作的動力。
2.關注公眾號懶人碼農,認真做好一件事比什么都重要。
3.也可添加微信【lazycode520】,拉你進技術群,長期交流學習。
“在看轉發”是最大的支持
總結
以上是生活随笔為你收集整理的jwt判断token是否过期_前端也得搞懂 JWT 这个知识点的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 捣蛋鹅手游第三关过关攻略
- 下一篇: 《创造吧我们的星球》迅猛龙啾捕捉位置一览