前端与 Spring Boot 后端无感 Token 刷新 - 从原理到全栈实践
1. 前言
在前后端分离的应用中,常用的身份认证方案是基于 JWT(JSON Web Token)。在保证安全性的同时,短生命周期的 Access Token 会带来频繁登录的体验痛点。为了解决这个问题,我们引入 Refresh Token 并结合无感刷新机制,让客户端在 Access Token 过期时自动刷新,而无需用户手动重新登录。
2. 为什么要无感刷新
在基于 Token 的用户认证系统中,通常会设计两种 Token:
Access Token:用于访问资源,有效期短(通常 15-30 分钟) Refresh Token:用于获取新 Access Token,有效期长(通常 7 天)
传统 Token 机制存在两大痛点:
频繁强制退出:Access Token 过期时用户需重新登录 安全隐患:延长 Access Token 有效期会增加安全风险
无感刷新解决了这些问题:
用户体验优先 Access Token 常设很短(如 5–15 分钟),若不自动刷新,登录态会频繁过期,用户被迫'重新登录',体验极差
安全与性能平衡 短生命周期的 Access Token 能减少被截获滥用的风险 结合 Refresh Token(相对较长有效期),可以在安全与便捷间找到最佳点
前后端解耦 通过前端拦截器统一处理过期场景,无须在各业务请求中散落重复逻辑 后端专注提供刷新接口与失效策略,无需关心前端实现细节
3. 无感刷新原理
3.1 无感刷新流程

3.2 关键技术点
双 Token 机制
Access Token:短时有效,携带用户身份和权限 Refresh Token:长期有效,专用于换取新的 Access Token
拦截与重试
- 前端在每次 API 请求中携带 Access Token;
- 若响应为 401 Unauthorized(或后端自定义过期码),前端拦截器自动调用刷新 token 接口,用 Refresh Token 获取新一对 Token;
- 获取成功后,前端重新发起失败的原始请求,用户无感知。
后端安全策略 将 Refresh Token 写入 Redis,并在刷新时做一次性或者滑动过期(可选)校验; 旧 Refresh Token 刷新后失效,防止被盗用。
4. 前端实现
下面以 Axios 为例演示拦截器逻辑。我们将 Tokens 保存在 localStorage 或者更安全的 HttpOnly Cookie 中(此处示例用 localStorage 方便演示)
// auth.js
axios ;
api = axios.({
: ,
});
() {
.();
}
() {
.();
}
() {
.(, accessToken);
.(, refreshToken);
}
api...( {
token = ();
(token) config.[] = ;
config;
});
isRefreshing = ;
subscribers = [];
() {
subscribers.( (newToken));
subscribers = [];
}
() {
subscribers.(cb);
}
api...( res, {
{ config, response } = error;
(response && response. === && !config.) {
(isRefreshing) {
( {
( {
config.[] = ;
((config));
});
});
}
config. = ;
isRefreshing = ;
api.(, { : () })
.( {
{ accessToken, refreshToken } = res.;
({ accessToken, refreshToken });
isRefreshing = ;
(accessToken);
config.[] = ;
(config);
})
.( {
isRefreshing = ;
.. = ;
.(err);
});
}
.(error);
});
api;


