SpringBoot實(shí)現(xiàn)無(wú)感刷新Token的項(xiàng)目實(shí)踐
引言
在當(dāng)前的Web應(yīng)用開(kāi)發(fā)中,JSON Web Tokens(JWT)作為一種輕量級(jí)的認(rèn)證協(xié)議,因其無(wú)狀態(tài)、自包含的特性而備受青睞。然而,JWT默認(rèn)的有效期有限,如何在不影響用戶體驗(yàn)的前提下實(shí)現(xiàn)Token的自動(dòng)刷新,即所謂的“無(wú)感刷新Token”,成為了許多開(kāi)發(fā)者關(guān)注的問(wèn)題。本文將深入探討如何在Spring Boot項(xiàng)目中實(shí)現(xiàn)無(wú)感刷新Token機(jī)制,并通過(guò)具體的示例代碼,逐步引導(dǎo)讀者掌握這一核心技術(shù)。
一、理解JWT與Token刷新
JWT基礎(chǔ)
JSON Web Tokens由頭部(Header)、載荷(Payload)和簽名(Signature)三部分組成,其中載荷部分可以攜帶過(guò)期時(shí)間(exp)。一旦Token過(guò)期,用戶必須重新登錄以獲取新的Token。
Token刷新
無(wú)感刷新Token,是指在用戶正常操作期間,系統(tǒng)在后臺(tái)自動(dòng)刷新Token的有效期,避免因Token過(guò)期而導(dǎo)致用戶被迫重新登錄。
二、基于Refresh Token的雙Token機(jī)制
Refresh Token
一種常見(jiàn)的無(wú)感刷新Token策略是采用雙Token機(jī)制,即同時(shí)發(fā)放Access Token和Refresh Token。Access Token用于身份驗(yàn)證,有效期較短;Refresh Token用于獲取新的Access Token,有效期較長(zhǎng)。
刷新流程
當(dāng)Access Token即將過(guò)期時(shí),客戶端攜帶Refresh Token向服務(wù)器請(qǐng)求新的Access Token,服務(wù)器驗(yàn)證Refresh Token有效后,頒發(fā)新的Access Token,并可以選擇性地更新Refresh Token。
三、Spring Boot實(shí)現(xiàn)無(wú)感刷新Token實(shí)戰(zhàn)
生成與解析JWT
首先,我們需要引入JWT相關(guān)的依賴(lài),如jjwt,并實(shí)現(xiàn)JWT的生成與解析。
// JWT工具類(lèi)
@Component
public class JwtUtil {
private String secret = "your-secret-key"; // 密鑰
public String generateToken(UserDetails userDetails) {
// 創(chuàng)建JWT并設(shè)置過(guò)期時(shí)間、載荷信息
// ...
return Jwts.builder()
.setSubject(userDetails.getUsername())
.setExpiration(new Date(System.currentTimeMillis() + expirationTime))
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public Boolean validateToken(String token, UserDetails userDetails) {
// 驗(yàn)證JWT有效性
// ...
}
public String refreshToken(String token) {
// 從token中提取subject(用戶名)
// 檢查Refresh Token有效性
// 生成新的Access Token
// ...
}
}
攔截器實(shí)現(xiàn)Token刷新
創(chuàng)建一個(gè)Spring Security攔截器,用于處理帶有JWT的HTTP請(qǐng)求,并在必要時(shí)自動(dòng)刷新Token。
@Component
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private JwtUtil jwtUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
String authorizationHeader = request.getHeader("Authorization");
if (authorizationHeader != null && authorizationHeader.startsWith("Bearer ")) {
String token = authorizationHeader.substring(7); // 獲取Token
String username = jwtUtil.extractUsername(token); // 提取用戶名
// 檢查T(mén)oken是否過(guò)期,如果即將過(guò)期,則嘗試刷新Token
if (jwtUtil.isTokenAboutToExpire(token)) {
String refreshedToken = jwtUtil.refreshToken(token);
// 更新響應(yīng)頭中的Token信息
// ...
}
}
chain.doFilter(request, response);
}
}
客戶端處理Token刷新
在前端或移動(dòng)端,通過(guò)監(jiān)聽(tīng)HTTP請(qǐng)求的響應(yīng)頭,獲取新的Access Token,并更新本地存儲(chǔ)。
四、進(jìn)一步優(yōu)化與注意事項(xiàng)
- Refresh Token安全性:為保證系統(tǒng)安全,Refresh Token應(yīng)具備足夠的保護(hù)措施,如限制其生命周期、禁止跨域使用、考慮綁定設(shè)備等。
- 離線刷新:對(duì)于某些場(chǎng)景,可以考慮實(shí)現(xiàn)離線刷新Token,即在客戶端檢測(cè)到Token即將過(guò)期時(shí),即使用戶尚未發(fā)起新的HTTP請(qǐng)求,也主動(dòng)向服務(wù)器請(qǐng)求新的Token。
- API Gateway集成:在微服務(wù)架構(gòu)中,可以利用API Gateway處理Token刷新,減輕服務(wù)端的壓力,同時(shí)實(shí)現(xiàn)更靈活的刷新策略。
五、結(jié)論
通過(guò)本文的闡述與示例,我們了解到如何在Spring Boot中實(shí)現(xiàn)基于JWT的無(wú)感刷新Token機(jī)制。實(shí)際應(yīng)用中,應(yīng)根據(jù)項(xiàng)目需求,結(jié)合最佳實(shí)踐,對(duì)Token刷新策略進(jìn)行合理設(shè)計(jì)與優(yōu)化,以實(shí)現(xiàn)既保證系統(tǒng)安全性,又能提供良好用戶體驗(yàn)的目標(biāo)。
到此這篇關(guān)于SpringBoot實(shí)現(xiàn)無(wú)感刷新Token的項(xiàng)目實(shí)踐的文章就介紹到這了,更多相關(guān)SpringBoot 無(wú)感刷新Token內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springmvc+spring+mybatis實(shí)現(xiàn)用戶登錄功能(下)
這篇文章主要為大家詳細(xì)介紹了springmvc+spring+mybatis實(shí)現(xiàn)用戶登錄功能的第二篇,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-07-07
手把手教你在eclipse創(chuàng)建第一個(gè)java?web項(xiàng)目并運(yùn)行
Eclipse是用來(lái)做開(kāi)發(fā)的自由集成開(kāi)發(fā)環(huán)境,這也是很多java程序員會(huì)使用的開(kāi)發(fā)環(huán)境,所以可以使用eclipse創(chuàng)建javaweb項(xiàng)目,下面這篇文章主要給大家介紹了關(guān)于如何在eclipse創(chuàng)建第一個(gè)java?web項(xiàng)目并運(yùn)行的相關(guān)資料,需要的朋友可以參考下2023-02-02
java數(shù)據(jù)結(jié)構(gòu)與算法之雙向循環(huán)隊(duì)列的數(shù)組實(shí)現(xiàn)方法
這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)與算法之雙向循環(huán)隊(duì)列的數(shù)組實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了雙向循環(huán)隊(duì)列的原理與數(shù)組實(shí)現(xiàn)技巧,并附帶說(shuō)明了該算法的用途,需要的朋友可以參考下2016-08-08
Java數(shù)據(jù)存儲(chǔ)的“雙子星”對(duì)決(Map和Set的區(qū)別)
文章主要介紹了Java中Map和Set兩種數(shù)據(jù)結(jié)構(gòu)的定義、實(shí)現(xiàn)、方法及應(yīng)用場(chǎng)景,Map用于存儲(chǔ)鍵值對(duì),鍵唯一,值可重復(fù);Set用于存儲(chǔ)唯一元素,無(wú)序,兩者都提供了豐富的操作方法,如添加、刪除、查找等,感興趣的朋友一起看看吧2025-02-02
SpringBoot使用PageHelper插件實(shí)現(xiàn)Mybatis分頁(yè)效果
這篇文章主要介紹了SpringBoot使用PageHelper插件實(shí)現(xiàn)Mybatis分頁(yè)效果,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的參考借鑒價(jià)值,需要的朋友可以參考下2024-02-02
在mybatis執(zhí)行SQL語(yǔ)句之前進(jìn)行攔擊處理實(shí)例
本篇文章主要介紹了在mybatis執(zhí)行SQL語(yǔ)句之前進(jìn)行攔擊處理實(shí)例,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2017-04-04
MybatisPlus:使用SQL保留字(關(guān)鍵字)的操作
這篇文章主要介紹了MybatisPlus:使用SQL保留字(關(guān)鍵字)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-11-11
java web手寫(xiě)實(shí)現(xiàn)分頁(yè)功能
這篇文章主要為大家詳細(xì)介紹了java web手寫(xiě)實(shí)現(xiàn)分頁(yè)功能的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-02-02

