双token无感刷新


🟢双token无感刷新

在这里插入图片描述

对于token无感刷新这个东西有复杂度的话,它主要在后端,它前端有啥复杂度,我估计吧,可能大多数对这个无感token刷新的概念不清除。所以本篇文章主要针对这块梳理一下。
双token无感刷新是一种在Web开发中常用的安全及用户体验优化技术,主要涉及到两种类型的token:Access Token(访问令牌)和Refresh Token(刷新令牌)。以下是对双token无感刷新的详细解释

1、token过期续期的五种方案对比

  • token过期后
    • 方案一:跳登录页=>突然需要登录体验不好
    • 方案二:刷新token重新发=>一直不用登录(但也可以设置过期时间)
    • 方案三:每次请求都刷新token=>服务器计算压力大
    • 方案四:token不过期、redis记录过期=>服务端维护用户身份
    • 方案五:双token(token1正常使用、token2用来刷新token)

2、双token的基本概念

  • Access Token(访问令牌):
    • 用户直接用于访问受保护资源的凭证。
    • 有效期较短,通常几分钟到几小时,一旦过期,用户需要重新认证以获取新的Access Token。
    • 即使Access Token被泄露,由于其有效期短,攻击者利用它进行不当操作的时间窗口有限。
  • Refresh Token(刷新令牌):
    • 用于在Access Token过期后或过期前的一个定时间内重新获取新的Access Token。
    • 有效期通常较长,甚至可以说是永久的,但出于安全考虑,一般会设置过期时间或使用次数限制。
    • Refresh Token通常不会直接发送给客户端,而是保存在服务器端或经过加密后存储在客户端本地(如localStorage或sessionStorage)。

3、双token无感刷新的原理

双token无感刷新的核心在于自动在后台处理Access Token的过期和刷新过程,而无需用户重新登录或感知到这一过程。具体步骤如下:
1.用户登录

  • 用户通过用户名(账号)、密码或其他认证方式向认证服务器请求授权。
  • 认证成功后,服务器返回Access Token和Refresh Token给前端。

2.请求受保护资源

  • 前端在访问受保护资源时,将Access Token放入请求头中发送给后端。
  • 如果Access Token有效,后端正常处理请求并返回结果。

3.请求受保护资源

  • 如果Access Token过期,后端会返回一个错误响应(如HTTP 401 Unauthorized)。
  • 前端在接收到错误响应后,自动在后台使用Refresh Token向认证服务器请求新的Access Token。
  1. 刷新Access Token
  • 认证服务器验证Refresh Token的有效性后,返回一个新的Access Token和(可选的)新的Refresh Token。
  • 前端更新本地存储的Access Token和Refresh Token,并重新发起之前的请求。

4、双token无感刷新的实现方式

在这里插入图片描述

双token无感刷新的实现通常依赖于前端和后端的配合。以下是一个简化的实现流程:

  1. 前端:
    • 在请求拦截器中拦截请求,检查Access Token是否即将过期或已过期。
    • 如果Access Token过期,则自动使用Refresh Token请求新的Access Token,并更新本地存储。
    • 将之前因Access Token过期而失败的请求重新发起。
  2. 将之前因Access Token过期而失败的请求重新发起。
    • 验证Access Token的有效性。。
    • 如果Access Token过期,返回错误响应,并允许使用Refresh Token来刷新Access Token。
    • 验证Refresh Token的有效性,并返回新的Access Token和(可选的)新的Refresh Token。

5.前端实现

  • 设置全局Axios拦截器
import axios from 'axios';  
import store from './store'; // 假设你有一个Vuex或Redux等状态管理库  
  
// 创建axios实例  
const service = axios.create({  
  baseURL: process.env.VUE_APP_BASE_API, // api的base_url  
  timeout: 5000 // 请求超时时间  
});  
  
// 请求拦截器  
service.interceptors.request.use(  
  config => {  
    // 从状态管理库或其他地方获取token  
    const accessToken = store.getters.accessToken;  
    if (accessToken) {  
      config.headers['Authorization'] = `Bearer ${accessToken}`;  
    }  
    return config;  
  },  
  error => {  
    // 处理请求错误  
    console.error('请求错误:', error); // for debug  
    Promise.reject(error);  
  }  
);  
  
// 响应拦截器  
service.interceptors.response.use(  
  response => {  
    // 响应正常则返回  
    return response;  
  },  
  error => {  
    // 响应错误处理  
    const { config, response, code } = error;  
    // 检查是否是401错误(未授权),且是由于token过期导致  
    if (response && response.status === 401 && response.data.code === 'TOKEN_EXPIRED') {  
      // 调用刷新token的函数  
      return refreshToken(config).then(accessToken => {  
        // token刷新成功,重新请求  
        config.headers['Authorization'] = `Bearer ${accessToken}`;  
        return service(config);  
      }).catch(err => {  
        // token刷新失败,清除tokens并跳转到登录页面  
        store.commit('clearTokens');  
        // 你可以在这里进行页面跳转等操作  
        window.location.href = '/login';  
        return Promise.reject(err);  
      });  
    }  
    // 其他错误直接返回  
    return Promise.reject(error);  
  }  
);  
  
// 刷新token的函数  
function refreshToken(config) {  
  return new Promise((resolve, reject) => {  
    const refreshToken = store.getters.refreshToken;  
    if (!refreshToken) {  
      reject('No refresh token');  
    }  
  
    // 发送请求以刷新token  
    axios.post('/api/auth/refresh-token', { refreshToken })  
      .then(response => {  
        // 更新state中的token  
        store.commit('updateAccessToken', response.data.accessToken);  
        resolve(response.data.accessToken);  
      })  
      .catch(err => {  
        reject(err);  
      });  
  });  
}  
  
export default service;
  • 状态管理(Vuex示例)
// store.js  
const store = new Vuex.Store({  
  state: {  
    accessToken: localStorage.getItem('accessToken') || '',  
    refreshToken: localStorage.getItem('refreshToken') || ''  
  },  
  getters: {  
    accessToken: state => state.accessToken,  
    refreshToken: state => state.refreshToken  
  },  
  mutations: {  
    updateAccessToken(state, accessToken) {  
      state.accessToken = accessToken;  
      localStorage.setItem('accessToken', accessToken);  
    },  
    clearTokens(state) {  
      state.accessToken = '';  
      state.refreshToken = '';  
      localStorage.removeItem('accessToken');  
      localStorage.removeItem('refreshToken');  
    }  
  }  
});  
  
export default store;



小结:双token无感刷新的优势

  1. 提升用户体验:用户无需频繁重新登录,即可持续访问受保护资源。
  2. 增强安全性:通过定期刷新Access Token,减少了Token被长期滥用的风险。同时,Refresh Token的有效期较长且存储更为安全,进一步提升了安全性。

综上所述,双token无感刷新是一种有效的安全及用户体验优化技术,它结合了Access Token和Refresh Token的优势,实现了在保障用户隐私和安全性的同时,提升用户体验的目标。

✒️总结

如果这篇【文章】有帮助到你💖,希望可以给我点个赞👍,创作不易,如果有对前端端或者对python感兴趣的朋友,请多多关注💖💖💖,咱们一起探讨和努力!!!
👨‍🔧 个人主页 : 前端初见

<think>嗯,用户想了解Vue2中的Token无感刷新机制。首先,我需要回忆一下这个机制的基本概念。Token通常指的是使用Access Token和Refresh Token的组合来实现用户认证,避免频繁登录。用户可能已经知道单Token的缺点,比如过期后需要重新登录,体验不好。所以Token的作用就是解决这个问题,实现无感刷新。 接下来,我应该解释清楚这两个Token的不同作用。Access Token有效期短,用于接口请求,而Refresh Token有效期长,用来获取新的Access Token。这个过程需要前端在检测到Access Token过期时,自动使用Refresh Token去请求新的Token,用户不会察觉到重新登录的过程。 然后,需要考虑如何在Vue2中具体实现。可能需要用到axios的拦截器,在请求发出前检查Token是否过期。如果过期,就发起一个刷新Token的请求,获取新的Access Token后重新发送原来的请求。这里要注意并发请求的处理,避免多个请求同时触发多次Token刷新。可能需要一个队列来存储等待的请求,等Token刷新完成后一起处理。 另外,用户可能关心如何检测Token是否过期。通常有两种方法:前端根据Token的过期时间戳判断,或者后端返回401状态码触发刷新。这两种方法各有优劣,前端校验可以减少不必要的请求,但需要准确的时间同步;后端触发则更可靠,但会多一次请求失败的情况。 还要提到安全性,Refresh Token需要安全存储,比如HttpOnly的Cookie,防止XSS攻击。同时,Refresh Token的过期处理,比如用户长时间不操作后需要重新登录,这也是需要考虑的。 可能还需要给出一些代码示例,比如axios拦截器的配置,如何封装刷新Token的函数,处理并发请求等。但要注意代码的正确性和兼容性,比如在Vue2中使用this.$axios或全局的axios实例。 最后,总结一下Token的优势,比如提升用户体验,减少密码输入次数,增强安全性等。同时提醒一些注意事项,比如Token的存储方式、网络错误处理、服务端的配合等。 用户可能是前端开发者,正在寻找在Vue2项目中实现无感刷新的解决方案。他们可能已经遇到了Token过期的问题,需要具体的实现步骤和最佳实践。深层需求可能是希望提升应用的用户体验,同时保证安全性,减少维护成本。需要确保回答结构清晰,步骤明确,代码示例正确,并且覆盖可能遇到的问题和解决方法。</think>好的,我将为您分步骤解释Vue2中Token无感刷新机制的实现原理和方案: 一、核心概念 1. Token组成: - Access Token(短期令牌):有效期短(如2小时),用于接口请求 - Refresh Token(刷新令牌):有效期长(如7天),存储于HttpOnly Cookie中 二、工作原理 1. 正常流程: $$流程图$$ 用户登录 → 获取Token → 携带Access Token请求 → 正常响应 2. 过期处理: 检测Access Token过期 → 使用Refresh Token获取新Access Token → 自动重发原请求 → 用户无感知 三、具体实现步骤(Vue2版) 1. 创建axios实例 ```javascript const service = axios.create({ baseURL: process.env.VUE_APP_BASE_API, timeout: 5000 }) ``` 2. 请求拦截器(添加Token) ```javascript service.interceptors.request.use(config => { const accessToken = localStorage.getItem('access_token') if (accessToken) { config.headers.Authorization = `Bearer ${accessToken}` } return config }) ``` 3. 响应拦截器(处理Token过期) ```javascript let isRefreshing = false let requests = [] service.interceptors.response.use( response => response, async error => { const { config, response } = error // 检测401状态码 if (response.status === 401 && !config._retry) { if (!isRefreshing) { isRefreshing = true config._retry = true try { const { data } = await refreshToken() localStorage.setItem('access_token', data.access_token) // 重发队列中的请求 requests.forEach(cb => cb(data.access_token)) requests = [] return service(config) } catch (e) { logout() return Promise.reject(e) } finally { isRefreshing = false } } // 将未完成的请求加入队列 return new Promise(resolve => { requests.push(token => { config.headers.Authorization = `Bearer ${token}` resolve(service(config)) }) }) } return Promise.reject(error) } ) ``` 4. 刷新Token函数 ```javascript function refreshToken() { return axios.post('/auth/refresh', {}, { withCredentials: true // 自动携带Refresh Token Cookie }) } ``` 四、关键问题处理 1. 并发请求控制: - 使用`isRefreshing`标志位防止重复刷新 - 使用请求队列`requests`存储等待中的请求 2. Token过期检测策略: - 方案一:前端预判(需解析JWT的exp字段) ```javascript function isTokenExpired(token) { const payload = JSON.parse(atob(token.split('.')[1])) return payload.exp * 1000 < Date.now() } ``` - 方案二:通过401状态码触发(更可靠) 五、安全增强措施 1. Refresh Token应设置为: ```http Set-Cookie: refresh_token=xxx; HttpOnly; Secure; SameSite=Strict; Path=/auth/refresh ``` 2. Token存储规范: - Access Token:内存或localStorage - Refresh Token:仅通过HttpOnly Cookie传输 六、注意事项 1. 服务端需要实现: - /auth/refresh 刷新接口 - 完整的JWT签发机制 - Refresh Token的轮换机制(可选) 2. 错误处理边界: - Refresh Token过期时强制退出登录 - 网络异常时的降级处理 七、优势总结 1. 用户体验:避免频繁登录 2. 安全性:缩短Access Token有效期,降低泄露风险 3. 兼容性:符合OAuth 2.0规范 实际部署时,建议配合以下措施: 1. 添加请求频率限制 2. 实施IP白名单检测 3. 定期进行安全审计
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

前端初见

打赏一下,解锁更多有趣内容

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值