无感刷新机制:智能系统的新宠儿?
创作时间:
作者:
@小白创作中心
无感刷新机制:智能系统的新宠儿?
引用
CSDN
等
9
来源
1.
https://blog.csdn.net/qq_36208612/article/details/139545599
2.
https://blog.csdn.net/m0_58600248/article/details/138916457
3.
https://m.blog.csdn.net/2401_89323925/article/details/145165700
4.
https://cloud.baidu.com/article/3211839
5.
https://blog.csdn.net/u012723183/article/details/136700195
6.
https://zhidao.baidu.com/question/1958727165501063588.html
7.
https://zhidao.baidu.com/question/2000771775062192627.html
8.
https://juejin.cn/post/7356240651040489487
9.
https://www.showapi.com/news/article/677dea394ddd79f11a1bcef4
在现代Web应用中,使用Token进行身份验证是一种常见方法。然而,当Token过期时,用户需要重新登录才能继续访问受保护资源,这会打断用户体验。引入了无感刷新机制后,即使Token即将过期,也能自动刷新,使用户在无感知的情况下继续操作。这种机制不仅提升了用户体验,还保证了系统的安全性。具体实现需根据项目需求和技术栈进行调整。
01
无感刷新机制的技术原理
无感刷新机制的核心是在Token过期前自动获取新的Token,确保用户会话的连续性。其基本流程如下:
- 检测过期:在请求发送前或响应返回时检查Token的有效期。
- 刷新逻辑:
- 使用Refresh Token获取新的Access Token(前端场景)。
- 通过过滤器自动刷新JWT Token(后端场景,如Spring Boot)。
这种机制的关键在于:
- 双Token机制:使用短有效期的Access Token和长有效期的Refresh Token。
- 自动刷新:在Token过期前自动发起刷新请求。
- 透明处理:刷新过程对用户完全透明,不影响正常使用。
02
前端实现示例
在前端应用中,通常使用Axios拦截器来实现无感刷新。以下是一个基于Vue.js的示例:
import axios from 'axios';
import store from './store';
axios.interceptors.request.use(config => {
const token = store.state.token;
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
}, error => {
return Promise.reject(error);
});
axios.interceptors.response.use(response => {
return response;
}, async function (error) {
if (error.response.status === 401) {
try {
const refreshToken = store.state.refreshToken;
const res = await axios.post('/refresh_token', { refreshToken });
store.commit('setToken', res.data.accessToken);
store.commit('setRefreshToken', res.data.refreshToken);
return axios(error.config);
} catch (refreshError) {
store.commit('logout');
router.push('/login');
}
}
return Promise.reject(error);
});
在这个示例中:
- 请求拦截器负责在请求头中添加Token。
- 响应拦截器捕获401错误(Token过期),触发刷新逻辑。
- 使用Refresh Token获取新Token,并更新存储中的Token。
- 刷新成功后重新发送原始请求。
03
后端实现示例
在后端,以Spring Boot为例,可以通过JWT工具类和过滤器实现无感刷新:
public class JwtTokenUtil {
public String generateToken(UserDetails userDetails) {
Map<String, Object> claims = new HashMap<>();
return Jwts.builder()
.setClaims(claims)
.setSubject(userDetails.getUsername())
.setIssuedAt(new Date())
.setExpiration(new Date(System.currentTimeMillis() + JWT_TOKEN_VALIDITY * 1000))
.signWith(SignatureAlgorithm.HS512, secret)
.compact();
}
public boolean validateToken(String token, UserDetails userDetails) {
final String username = getUsernameFromToken(token);
return (username.equals(userDetails.getUsername()) && !isTokenExpired(token));
}
private boolean isTokenExpired(String token) {
final Date expiration = getExpirationDateFromToken(token);
return expiration.before(new Date());
}
}
public class JwtRequestFilter extends OncePerRequestFilter {
@Autowired
private JwtUserDetailsService userDetailsService;
@Autowired
private JwtTokenUtil jwtTokenUtil;
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
throws ServletException, IOException {
final String requestTokenHeader = request.getHeader("Authorization");
String username = null;
String jwtToken = null;
if (requestTokenHeader != null && requestTokenHeader.startsWith("Bearer ")) {
jwtToken = requestTokenHeader.substring(7);
try {
username = jwtTokenUtil.getUsernameFromToken(jwtToken);
} catch (IllegalArgumentException e) {
logger.warn("Unable to get JWT Token");
} catch (ExpiredJwtException e) {
logger.warn("JWT Token has expired");
}
}
if (username != null && SecurityContextHolder.getContext().getAuthentication() == null) {
UserDetails userDetails = this.userDetailsService.loadUserByUsername(username);
if (jwtTokenUtil.validateToken(jwtToken, userDetails)) {
UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(
userDetails, null, userDetails.getAuthorities());
usernamePasswordAuthenticationToken
.setDetails(new WebAuthenticationDetailsSource().buildDetails(request));
SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken);
}
}
chain.doFilter(request, response);
}
}
在这个示例中:
JwtTokenUtil负责生成和验证JWT Token。JwtRequestFilter在请求到达控制器前检查Token,必要时自动刷新并放行。
04
微信小程序实现
在微信小程序中,无感刷新机制的实现与前端Web应用类似,但需要特别注意本地存储的安全性:
- 本地存储:保存Token和过期时间。
- 启动时验证:在
onLaunch或onShow中检查Token有效性,提前刷新即将过期的Token。 - 登录与刷新:提供刷新Token接口,失败时重新登录。
// app.js
App({
onLaunch: function () {
const token = wx.getStorageSync('token');
const refreshToken = wx.getStorageSync('refreshToken');
const tokenExpireTime = wx.getStorageSync('tokenExpireTime');
if (token && refreshToken && tokenExpireTime > Date.now()) {
this.checkTokenValidity();
}
},
checkTokenValidity: function () {
wx.request({
url: 'https://your-api.com/check_token',
method: 'GET',
header: {
'Authorization': 'Bearer ' + wx.getStorageSync('token')
},
success: (res) => {
if (res.data.code === 401) {
this.refreshToken();
}
}
});
},
refreshToken: function () {
wx.request({
url: 'https://your-api.com/refresh_token',
method: 'POST',
data: {
refreshToken: wx.getStorageSync('refreshToken')
},
success: (res) => {
if (res.data.code === 200) {
wx.setStorageSync('token', res.data.token);
wx.setStorageSync('tokenExpireTime', Date.now() + res.data.expiresIn * 1000);
} else {
wx.removeStorageSync('token');
wx.removeStorageSync('refreshToken');
wx.navigateTo({
url: '/pages/login/login'
});
}
}
});
}
});
05
最佳实践
- 双Token机制:Access Token设置较短有效期(如15分钟),Refresh Token设置较长有效期(如1小时)。
- 前端实现要点:
- 使用拦截器处理Token刷新逻辑。
- 设置标志位防止重复刷新。
- 缓存待执行的请求,在Token刷新成功后重新发送。
- 后端实现要点:
- 提供安全的Token刷新接口。
- 使用过滤器检查Token有效性。
- 确保Refresh Token的安全存储和传输。
- 错误处理:如果Token刷新失败,应引导用户重新登录,并提供友好的提示信息。
- 安全性考虑:
- Refresh Token也需要定期更新,避免长期暴露。
- 注意防止XSS和CSRF攻击。
- 使用HTTPS确保数据传输安全。
06
未来趋势
随着技术的发展,无感刷新机制可能会有以下改进方向:
- 智能刷新策略:根据用户行为和网络状况动态调整刷新时机。
- 多因素认证集成:结合生物识别等技术,提供更安全的无感认证体验。
- 统一身份管理:在跨平台和跨设备场景下实现无缝的无感刷新。
- 隐私保护增强:在保证用户体验的同时,进一步加强用户隐私保护。
无感刷新机制通过智能的技术手段,解决了传统Token认证方式中用户需要频繁登录的问题,既提升了用户体验,又保证了系统的安全性。随着技术的不断进步,这种机制将在更多场景中得到应用,为用户带来更加便捷和安全的使用体验。
热门推荐
塑料桶养泥鳅技术详解
归芍地黄丸配伍禁忌大揭秘:这些药物不能同时服用
高尿酸患者可以吃牛肉吗?答案令人惊喜
双鸭山到七一:自驾3小时20分钟,火车需中转5小时
海南温泉度假地图:八大温泉区特色与体验详解
安卓手机刷机,你真的敢尝试吗?
隔断艺术:打造高颜值家居空间的点睛之笔
68种常见兰花品种与花色图谱探秘,揭示兰花之美
苏打粉不只是饮料,还有这些神奇功效!
改装车玩家必看!合法改装的正确姿势
紧邻地铁2号线,15路公交直达,盛世长安小区交通全解析
名中医龙祖宏:口苦不只是肝胆湿热,三种类型辨证施治
抗性糊精:无糖食品界的“健康神器”
西安到武汉自驾游:穿越千年古都与现代江城的视觉盛宴
北京车祸引关注:保险公司代位追偿如何保障车主权益
川贝炖雪梨:哮喘患者的冬季食疗佳品
职场竞争力爆棚:电脑基础操作必修课
西葫芦鸡蛋饼:健康又美味的低脂零食
油菜花海摄影技巧全攻略:10个实用技巧让你秒变春日女神
重庆法院判例:婚外情生子侵犯配偶权,需赔偿精神损失
龙华山:赣州的自然明珠,四季美景与文化魅力的完美融合
北豆腐炒法的健康秘诀
屈原与端午节:千年情缘,万世流芳
家用净水器废水比选购指南:技术创新实现环保节水
《舌尖上的中国》教你健康做红烧肉
无限暖暖心愿原野游记:任务攻略大揭秘
四川攀枝花:20℃暖冬里的春节度假胜地
生烤番茄蛋黄盅:一道融合中西的创意菜品
延迟退休遇上“健康工作7年”:如何保障劳动者权益?
新能源汽车购置税减免新政出台,换电车型需满足新安全标准