JWT概述以及Token刷新機(jī)制詳解
一、概述
什么是JWT,簡單的說就是一個(gè)存儲在請求頭中的字符串,包含了用戶信息和校驗(yàn)信息。較為正式一點(diǎn)的來說, JWT(JSON Web Token)是一種無狀態(tài)的身份認(rèn)證機(jī)制,通常用于前后端分離項(xiàng)目。
它具有以下特點(diǎn):
- 無狀態(tài):JWT是基于客戶端存儲的,不會存儲在服務(wù)端,減輕了服務(wù)端的存儲壓力
- 高性能:每次請求都會攜帶JWT,而不用查詢數(shù)據(jù)庫或緩存,就能完成身份認(rèn)證
- 對于跨域友好:由于是通過HTTP請求進(jìn)行傳輸,不存在跨域限制
二、JWT組成
JWT由三部分組成,各部分用.隔開。header.payload.signature。
- header(頭部):用于存儲JWT類型和加密算法。
- payload(負(fù)載):存儲數(shù)據(jù),如用戶id,過期時(shí)間等。
- signature(簽名):由密鑰(通常是一個(gè)對稱密鑰或者非對稱密鑰) 對前兩部分利用某種特定的加密算法進(jìn)行簽名,防止篡改。
三、JWT認(rèn)證
用戶輸入賬號密碼,經(jīng)過服務(wù)端校驗(yàn)成功后,就會生成一個(gè)JWT,首先選擇其加密算法類型,如 HS256,將這一部分內(nèi)容放入頭部中,然后在負(fù)載中放入用戶id,過期時(shí)間等信息;然后會使用一個(gè) 密鑰 對前兩部分進(jìn)行 HMAC-SHA256 簽名,防止篡改。然后將JWT返回給客戶端,客戶端將其存儲在本地緩存中。
以后的每次請求中,都帶上該JWT。服務(wù)端從請求頭請求頭中獲取該JWT,然后使用相同的密鑰對其進(jìn)行驗(yàn)證,若驗(yàn)證成功則獲取負(fù)載中的信息,對其中的信息進(jìn)行驗(yàn)證,一般是查詢db,驗(yàn)證用戶id的有效性。然后才對該請求進(jìn)行放行。

四、與傳統(tǒng)session相比較
JWT與傳統(tǒng)session的區(qū)別:
- JWT是存儲在客戶端,服務(wù)端 通過請求頭獲取,而session通常是存儲在服務(wù)端,一般通過查詢緩存獲取
- JWT更適合分布式項(xiàng)目,而session則需要使用共享方案來實(shí)現(xiàn)
- JWT容易被篡改,而session由于是存儲在服務(wù)端,更安全
- 服務(wù)器不能更改JWT的過期時(shí)間和刪除它,而對于session來說較為容易
五、對于token失效的解決策略
我們之前討論的 JWT 認(rèn)證 基本流程是:
- 用戶登錄后,服務(wù)器生成一個(gè) Access Token(通常較短有效期,如 15 分鐘),并返回給客戶端。
- 客戶端每次請求時(shí)都會攜帶 Access Token,服務(wù)器通過驗(yàn)證 Access Token 來確認(rèn)用戶身份。
但存在一定問題:
- Access Token 一旦過期,用戶需要重新登錄才能獲取新的 Access Token。
- 頻繁要求用戶登錄會影響用戶體驗(yàn),尤其是對于需要長時(shí)間使用的app
所以引入 Refresh Token機(jī)制來解決上述問題:
Refresh Token 是一個(gè)長期有效的 Token,一般有效期7-30天,它的作用是用來刷新已過期的 Access Token。
工作流程
用戶登錄:
- 用戶提交用戶名和密碼給服務(wù)器。
- 服務(wù)器驗(yàn)證成功后,生成 Access Token 和 Refresh Token。
- Access Token 有較短的有效期(例如 15 分鐘),而 Refresh Token 有較長的有效期(例如 7 天)。
Access Token 過期:
- 當(dāng) Access Token 過期時(shí),客戶端發(fā)送請求到服務(wù)器,攜帶過期的 Access Token和有效的 Refresh Token,這時(shí)候客戶端不需要讓用戶重新登錄,而是使用Refresh Token來向服務(wù)器請求刷新一個(gè)新的 Access Token。
- 服務(wù)器驗(yàn)證 Refresh Token,如果有效,則生成新的 Access Token 和新的 Refresh Token(防止Refresh Token被盜用)返回給客戶端。
- 客戶端用新的 Access Token 繼續(xù)訪問 API。
Token 刷新失敗:
- 如果 Refresh Token 也過期,或者 Refresh Token 被篡改,服務(wù)器會要求用戶重新登錄。
注意:
- Refresh Token 本身不會直接用于訪問 API,僅用于刷新 Access Token。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
將Springboot項(xiàng)目升級成Springcloud項(xiàng)目的圖文教程
本文主要介紹了將Springboot項(xiàng)目升級成Springcloud項(xiàng)目,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-06-06
spring的data派生查詢機(jī)制的實(shí)現(xiàn)
SpringData的派生查詢是一種通過方法名約定自動(dòng)生成數(shù)據(jù)庫查詢的機(jī)制,無需手動(dòng)編寫SQL或JPQL,下面就來介紹一下spring data派生查詢的實(shí)現(xiàn),感興趣的可以了解一下2025-03-03
JAVA 多線程之信號量(Semaphore)實(shí)例詳解
這篇文章主要介紹了JAVA 多線程之信號量(Semaphore)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-01-01
MyBatis中${}?和?#{}?有什么區(qū)別小結(jié)
${}?和?#{}?都是?MyBatis?中用來替換參數(shù)的,它們都可以將用戶傳遞過來的參數(shù),替換到?MyBatis?最終生成的?SQL?中,但它們區(qū)別卻是很大的,今天通過本文介紹下MyBatis中${}?和?#{}?有什么區(qū)別,感興趣的朋友跟隨小編一起看看吧2022-11-11
java多線程實(shí)現(xiàn)同步鎖賣票實(shí)戰(zhàn)項(xiàng)目
本文主要介紹了java多線程實(shí)現(xiàn)同步鎖賣票實(shí)戰(zhàn)項(xiàng)目,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01
Java使用PreparedStatement接口及ResultSet結(jié)果集的方法示例
這篇文章主要介紹了Java使用PreparedStatement接口及ResultSet結(jié)果集的方法,結(jié)合實(shí)例形式分析了PreparedStatement接口及ResultSet結(jié)果集的相關(guān)使用方法與操作注意事項(xiàng),需要的朋友可以參考下2018-07-07
解決OpenFeign遠(yuǎn)程調(diào)用返回的對象總是null問題
OpenFeign在SpringCloud中用于遠(yuǎn)程調(diào)用,配置簡單,在使用Ribbon或Hystrix時(shí),需要注意path參數(shù)必須以/開頭,否則回參會是null2024-11-11

