经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » JS/JS库/框架 » Vue.js » 查看文章
业务场景---Token无感刷新
来源:cnblogs  作者:最小生成树  时间:2024/7/29 9:30:00  对本文有异议

业务场景描述

假设用户正在填写一个复杂的表单,由于表单内容繁多,用户花费了很长时间才填完。这时,如果Token已经过期,系统会让用户重新登录,这种体验显然是非常糟糕的。为了避免这种情况,我们需要在Token即将过期或已经过期时,自动刷新Token,而不影响用户正在进行的操作。

技术实现思路

一、准备工作

  1. 前端框架选择:本文以Vue.js为例,结合Vue Router和Axios来实现Token无感刷新机制。
  2. 后端支持:后端需要提供刷新Token的接口,当接收到旧的Token时返回一个新的Token。

二、关键技术点

  1. 拦截请求:使用Axios拦截器来检测每一个请求的状态,如果发现Token过期,则触发刷新Token的逻辑。
  2. 刷新Token:实现一个专门用于刷新Token的方法,该方法会在旧的Token过期时自动调用并更新Token。
  3. 请求队列:在刷新Token期间,暂停其他需要Token的请求,待Token刷新成功后,重新发送这些请求。

三、具体实现步骤

1. 配置Axios拦截器

首先,配置Axios拦截器来检测请求和响应的状态,并在Token过期时触发刷新Token的逻辑。

  1. import axios from 'axios';
  2. import store from './store'; // 假设使用Vuex来管理全局状态
  3. import router from './router';
  4. let isRefreshing = false;
  5. let requests = [];
  6. axios.interceptors.request.use(
  7. config => {
  8. const token = store.state.token;
  9. if (token) {
  10. config.headers['Authorization'] = 'Bearer ' + token;
  11. }
  12. return config;
  13. },
  14. error => {
  15. return Promise.reject(error);
  16. }
  17. );
  18. axios.interceptors.response.use(
  19. response => {
  20. return response;
  21. },
  22. error => {
  23. const { config, response } = error;
  24. const originalRequest = config;
  25. if (response && response.status === 401) {
  26. if (!isRefreshing) {
  27. isRefreshing = true;
  28. return refreshToken().then(newToken => {
  29. store.commit('setToken', newToken);
  30. originalRequest.headers['Authorization'] = 'Bearer ' + newToken;
  31. processQueue(null, newToken);
  32. return axios(originalRequest);
  33. }).catch(err => {
  34. processQueue(err, null);
  35. store.commit('logout');
  36. router.push('/login');
  37. return Promise.reject(err);
  38. }).finally(() => {
  39. isRefreshing = false;
  40. });
  41. } else {
  42. return new Promise((resolve, reject) => {
  43. requests.push((token) => {
  44. originalRequest.headers['Authorization'] = 'Bearer ' + token;
  45. resolve(axios(originalRequest));
  46. });
  47. });
  48. }
  49. }
  50. return Promise.reject(error);
  51. }
  52. );
  53. function processQueue(error, token = null) {
  54. requests.forEach(promise => {
  55. if (error) {
  56. promise.reject(error);
  57. } else {
  58. promise.resolve(token);
  59. }
  60. });
  61. requests = [];
  62. }

 

2. 实现刷新Token的方法

接下来,实现一个用于刷新Token的方法refreshToken。这个方法会调用后端接口来获取新的Token。

  1. function refreshToken() {
  2. return new Promise((resolve, reject) => {
  3. axios.post('/auth/refresh', {
  4. refreshToken: store.state.refreshToken
  5. }).then(response => {
  6. if (response.data.success) {
  7. resolve(response.data.token);
  8. } else {
  9. reject(response.data.message);
  10. }
  11. }).catch(error => {
  12. reject(error);
  13. });
  14. });
  15. }

 

3. 更新Vuex状态管理

确保在Vuex中有相关的状态和方法来管理Token和用户登录状态。

 

  1. const store = new Vuex.Store({
  2. state: {
  3. token: localStorage.getItem('token') || '',
  4. refreshToken: localStorage.getItem('refreshToken') || '',
  5. user: {}
  6. },
  7. mutations: {
  8. setToken(state, token) {
  9. state.token = token;
  10. localStorage.setItem('token', token);
  11. },
  12. setRefreshToken(state, refreshToken) {
  13. state.refreshToken = refreshToken;
  14. localStorage.setItem('refreshToken', refreshToken);
  15. },
  16. logout(state) {
  17. state.token = '';
  18. state.refreshToken = '';
  19. state.user = {};
  20. localStorage.removeItem('token');
  21. localStorage.removeItem('refreshToken');
  22. }
  23. }
  24. });

 

4. 处理登录逻辑

确保在用户登录时,正确地存储Token和刷新Token。

  1. function login(credentials) {
  2. return axios.post('/auth/login', credentials).then(response => {
  3. store.commit('setToken', response.data.token);
  4. store.commit('setRefreshToken', response.data.refreshToken);
  5. });
  6. }

 

总结:当用户在填写复杂表单时,即使Token过期也不会中断他们的操作,从而提供了更好的用户体验。这个机制不仅适用于表单填写,还可以广泛应用于任何需要长时间交互的Web应用场景中。

 

原文链接:https://www.cnblogs.com/zx618/p/18326822

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号