單 Token 面臨「短過期不安全、長過期體驗差」兩難。雙 Token 方案:Access Token(短效,如 1h)+ Refresh Token(長效,如 30 天),Access 過期時用 Refresh 換新 Access,無需用戶重新登錄。
import com.google.common.hash.Hashing;
import com.google.common.base.Charsets;
import org.apache.commons.lang.time.FastDateFormat;
import java.util.Date;
public class TokenUtils {
private static final String PRIVATE_KEY = "fdas34ljfr好sja@#8$%dfkl;js&4*daklfjsdl;akfjsa342";
// 生成 Access Token(精確到小時)
public static String getToken(String password) {
return Hashing.md5().newHasher()
.putString(password, Charsets.UTF_8)
.putString(PRIVATE_KEY, Charsets.UTF_8)
.putString(getDate(), Charsets.UTF_8)
.hash().toString();
}
// 驗證 Access Token
public static boolean validToken(String token, String password) {
return getToken(password).equals(token);
}
// 獲取「當前小時」字符串 yyyyMMddHH
public static String getDate() {
return FastDateFormat.getInstance("yyyyMMddHH").format(new Date());
}
// 獲取「下一小時」字符串(用於預簽發/平滑過渡)
public static String getNextHour(Date now) {
return FastDateFormat.getInstance("yyyyMMddHH")
.format(new Date(now.getTime() + 3600_000));
}
}
登錄成功 → 返回 {access_token, refresh_token, expires_in: 3600}
↓
業務請求攜帶 Access Token
↓
服務端 validToken() 校驗
├─ 通過 → 正常響應
└─ 失效 → 客戶端攜帶 Refresh Token 請求 /refresh
↓
校驗 Refresh Token(查 Redis/DB、核對簽名)
├─ 通過 → 簽發新 Access Token + 新 Refresh Token(可選輪換)
└─ 失效 → 返回 401,引導重新登錄
jti (JWT ID) 防重放本文提供基於「密碼+私鑰+時間窗」的無狀態 Access Token 算法,結合雙 Token 思想,可快速構建「體驗好、安全性可控」的鑒權體系。生產環境建議遷移至 JWT + Redis 方案以支持更豐富的聲明與撤銷策略。