token 過(guò)期后,如何自動(dòng)續(xù)期?
來(lái)源:toutiao.com/article/6995179162675790350
JWT?token的 payload 部分是一個(gè)json串,是要傳遞數(shù)據(jù)的一組聲明,這些聲明被JWT標(biāo)準(zhǔn)稱(chēng)為claims。
JWT標(biāo)準(zhǔn)里面定義的標(biāo)準(zhǔn)claim包括:
iss(Issuser):JWT的簽發(fā)主體;sub(Subject):JWT的所有者;aud(Audience):JWT的接收對(duì)象;exp(Expiration time):JWT的過(guò)期時(shí)間;nbf(Not Before):JWT的生效開(kāi)始時(shí)間;iat(Issued at):JWT的簽發(fā)時(shí)間;jti(JWT ID):是JWT的唯一標(biāo)識(shí)。
除了以上標(biāo)準(zhǔn)聲明以外,我們還可以自定義聲明。以 com.auth0 為例,下面代碼片段實(shí)現(xiàn)了生成一個(gè)帶有過(guò)期時(shí)間的token.
String?token?=?JWT.create()
????.withIssuer(ISSUER)
????.withIssuedAt(new?Date(currentTime))//?簽發(fā)時(shí)間
????.withExpiresAt(new?Date(currentTime?+?EXPIRES_IN?*?1000?*?60))//?過(guò)期時(shí)間戳
????.withClaim("username",?username)//自定義參數(shù)
????.sign(Algorithm.HMAC256(user.getPassword()));
其中:
withIssuer()?設(shè)置簽發(fā)主體;withIssuedAt()?設(shè)置簽發(fā)時(shí)間;withExpiresAt()?設(shè)置過(guò)期時(shí)間戳,過(guò)期的時(shí)長(zhǎng)為 EXPIRES_IN (單位秒);withClaim()?設(shè)置自定義參數(shù)。
JWT設(shè)置了過(guò)期時(shí)間以后,一定超過(guò),那么接口就不能訪問(wèn)了,需要用戶(hù)重新登錄獲取token。如果經(jīng)常需要用戶(hù)重新登錄,顯然這種體驗(yàn)不是太好,因此很多應(yīng)用會(huì)采用token過(guò)期后自動(dòng)續(xù)期的方案,只有特定條件下才會(huì)讓用戶(hù)重新登錄。
token過(guò)期的續(xù)期方案
解決token過(guò)期的續(xù)期問(wèn)題可以有很多種不同的方案,這里舉一些比較有代表性的例子。首先我們看一個(gè)單token方案,這個(gè)方案除了可以實(shí)現(xiàn)token續(xù)期以外,還可以實(shí)現(xiàn)某些條件下的強(qiáng)制重新登錄。
單token方案

將 token 過(guò)期時(shí)間設(shè)置為15分鐘; 前端發(fā)起請(qǐng)求,后端驗(yàn)證 token 是否過(guò)期;如果過(guò)期,前端發(fā)起刷新token請(qǐng)求,后端為前端返回一個(gè)新的token; 前端用新的token發(fā)起請(qǐng)求,請(qǐng)求成功; 如果要實(shí)現(xiàn)每隔72小時(shí),必須重新登錄,后端需要記錄每次用戶(hù)的登錄時(shí)間;用戶(hù)每次請(qǐng)求時(shí),檢查用戶(hù)最后一次登錄日期,如超過(guò)72小時(shí),則拒絕刷新token的請(qǐng)求,請(qǐng)求失敗,跳轉(zhuǎn)到登錄頁(yè)面。
另外后端還可以記錄刷新token的次數(shù),比如最多刷新50次,如果達(dá)到50次,則不再允許刷新,需要用戶(hù)重新授權(quán)。
上面介紹的單token方案原理比較簡(jiǎn)單。下面我們?cè)倏匆粋€(gè)雙token方案。
雙token方案
登錄成功以后,后端返回? access_token?和?refresh_token,客戶(hù)端緩存此兩種token;使用? access_token?請(qǐng)求接口資源,成功則調(diào)用成功;如果token超時(shí),客戶(hù)端攜帶?refresh_token?調(diào)用token刷新接口獲取新的?access_token;后端接受刷新token的請(qǐng)求后,檢查? refresh_token?是否過(guò)期。如果過(guò)期,拒絕刷新,客戶(hù)端收到該狀態(tài)后,跳轉(zhuǎn)到登錄頁(yè);如果未過(guò)期,生成新的?access_token?返回給客戶(hù)端。客戶(hù)端攜帶新的? access_token?重新調(diào)用上面的資源接口。客戶(hù)端退出登錄或修改密碼后,注銷(xiāo)舊的token,使? access_token?和?refresh_token?失效,同時(shí)清空客戶(hù)端的?access_token?和?refresh_toke。
微信網(wǎng)頁(yè)授權(quán)是通過(guò)OAuth2.0機(jī)制實(shí)現(xiàn)的,也使用了雙token方案。

微信網(wǎng)頁(yè)授權(quán)方案
用戶(hù)在第三方應(yīng)用的網(wǎng)頁(yè)上完成微信授權(quán)以后,第三方應(yīng)用可以獲得 code(授權(quán)碼)。code的超時(shí)時(shí)間為10分鐘,一個(gè)code只能成功換取一次access_token即失效。 第三方應(yīng)用通過(guò)code獲取網(wǎng)頁(yè)授權(quán)憑證access_token和刷新憑證 refresh_token。 access_token是調(diào)用授權(quán)關(guān)系接口的調(diào)用憑證,由于access_token有效期(2個(gè)小時(shí))較短,當(dāng)access_token超時(shí)后,可以使用refresh_token進(jìn)行刷新。 refresh_token擁有較長(zhǎng)的有效期(30天),當(dāng)refresh_token失效的后,需要用戶(hù)重新授權(quán)。
后端實(shí)現(xiàn)token過(guò)期還可以利用Redis來(lái)存儲(chǔ)token,設(shè)置redis的鍵值對(duì)的過(guò)期時(shí)間。如果發(fā)現(xiàn)redis中不存在token的記錄,說(shuō)明token已經(jīng)過(guò)期了。
*
IDEA2022.1版本最近發(fā)布了,想要早點(diǎn)嘗鮮的小伙伴,可以去下載了。
????點(diǎn)擊「原文閱讀」,可以獲取最新激活。
