前言
在如今这个追求极致用户体验的时代,想必大家都有过这样的经历:正沉浸在刷视频、玩游戏等操作中,突然蹦出一则 “登录已过期,请重新登录” 的提示。瞬间打断了节奏,兴致全无,还要重新输入密码登录,体验感极差。
为了解决这一痛点,“无感刷新” 技术应运而生。它的核心就在于利用双 Token 机制,让用户在毫无察觉的情况下完成身份续期,始终保持在线状态。下面,就带你深入探究这一技术的奥秘。
一、双 Token 机制浅析
所谓双 Token,即一个短令牌 access_token 和一个长令牌 refresh_token。
- access_token :有效期短暂,通常设定为 1 小时左右,主要用于日常的各类请求操作。就像一把临时钥匙,开启对应的功能权限,但使用时间受限。
- refresh_token :有效期较长,一般为 7 天至 30 天不等,其专属职责是用于刷新令牌。
工作流程如下:
当用户成功登录后,系统会同时颁发这两个令牌。随后,access_token 会附带在每一次的请求中,用于验证用户身份。一旦 access_token 过期,此时 refresh_token 就登场发挥作用了,它会默默地向服务器请求获取新的双令牌,实现自动续期,整个过程用户毫无察觉,仿佛一切都在 “幕后” 有序运转。
二、前端实现思路(以 Vue + Axios 为例)
1. 登录与存储令牌
在用户登录时,通过发送账号密码等信息到后端进行验证。若登录成功,后端会返回双令牌,前端则使用 localStorage 将其妥善保存。
const login = async () => {
const res = await userLogin(user); // 账号密码登录请求
localStorage.setItem('access_token', res.access_token);
localStorage.setItem('refresh_token', res.refresh_token);
}
2. 请求自动携带令牌
借助 Axios 的请求拦截器,确保在每次发起请求时,会自动从 localStorage 中取出 access_token,并将其添加到请求头的 Authorization 字段中,如此一来,后端就能依据该令牌验证用户身份。
api.interceptors.request.use(config => {
const access_token = localStorage.getItem('access_token');
if (access_token) {
config.headers.Authorization = `Bearer ${access_token}`;
}
return config;
})
3. 智能令牌刷新
重点来了,当响应拦截器捕获到 401 状态码(表示登录过期)时,就会触发令牌刷新过程。不过要先验证 refresh_token 是否失效,若失效则直接重定向到登录页面;若未失效,则利用 refresh_token 请求新的双令牌,并将原失败的请求重新发送,保证用户操作的连贯性。
api.interceptors.response.use(
response => response,
async error => {
const { data, status, config } = error.response;
if (status === 401 && config.url !== '/refresh') {
const res = await refreshToken(); // 刷新令牌函数
if (res.status === 200) {
return api(config); // 重新发起请求
} else {
window.location.href = '/login'; // 失败去登录
}
}
}
)
三、后端实现要点(以 Node.js + Express 为例)
1. 生成双令牌
后端在用户登录成功后,利用 jwt(JsonWebToken)等技术,分别生成 access_token 和 refresh_token,二者区别在于有效期时长,通过不同的过期时间参数来设定。
const access_token = generateToken(user, '1h'); // 生成1小时token
const refresh_token = generateToken(user, '7d'); // 生成7天token
2. 令牌刷新接口
专门搭建一个接口,用于处理令牌刷新请求。接收客户端传来的旧 refresh_token,先验证其有效性,若有效,则依据其中的用户信息生成新的双令牌并返回给前端;若无效,则返回相应错误提示,促使前端引导用户重新登录。
app.get('/refresh', (req, res) => {
const oldRefreshToken = req.query.token;
try {
const userData = verifyToken(oldRefreshToken); // 验证token
const newAccessToken = generateToken(userData, '1h');
const newRefreshToken = generateToken(userData, '7d');
res.json({ access_token: newAccessToken, refresh_token: newRefreshToken });
} catch (error) {
res.status(401).send('令牌失效');
}
})
四、流程图示
大致流程如下:
用户发起请求 → 携带 access_token → 服务端验证 ↓ 无效 / 过期 触发 401 错误 → 前端拦截 → 发起 refresh_token 刷新请求 ↓ 刷新成功 更新本地令牌 → 重新发送原请求 → 用户无感知 ↓ 刷新失败 跳转登录页面 → 需要重新认证
五、安全注意事项
- refresh_token 有效期设置要合理 :它虽需长期有效,但不可无限制拉长,通常 7 - 30 天为宜,要在安全与体验间找到平衡。
- 必须使用 HTTPS :如此可有效防止令牌在传输过程中被中间人窃取,保障数据传输的安全性。
- 存储令牌要谨慎 :避免将令牌明文存储,使用浏览器 localStorage 时,要强化 XSS(跨站脚本攻击)防护,防止恶意脚本窃取令牌。
双 Token 无感刷新技术,恰似一位 “幕后助手”,悄无声息地保障着用户长时间的流畅在线体验,减少了因登录过期带来的诸多不便,极大地提升了用户满意度。当下,众多互联网应用都已融入此项技术,你是不是也感受到了它带来的便捷呢?