axios 刷新令牌后返回原始请求

e4yzc0pl  于 2024-01-07  发布在  iOS
关注(0)|答案(1)|浏览(143)

我通过Axios通过pinia存储发出某些请求。这些请求通过计时器,可以发送多个请求。我的服务器使用需要刷新的令牌。我已经编写了一个拦截器,用于检查访问令牌的过期时间并在其无效之前发送刷新令牌。在我处理刷新令牌时发生的所有请求都存储在一个数组中。现在这可以工作了,但是我没有返回到请求的地方(pinia store),所以数据没有调整。

  1. import axios from 'axios';
  2. import {useAuthStore} from "@/stores/Authentication/AppAuthStore.js";
  3. import VueJwtDecode from 'vue-jwt-decode';
  4. axios.defaults.baseURL = import.meta.env.VITE_API_ENDPOINT;
  5. axios.defaults.maxRedirects = 0;
  6. let refreshing_token = null;
  7. let myTimeout= null;
  8. let busy = false;
  9. let requestArray = [];
  10. const baseURL = import.meta.env.VITE_API_ENDPOINT;
  11. axios.interceptors.request.use( async req =>{
  12. if (req.url.endsWith("refresh")) {
  13. // if we are making a refresh token call, return it to prevent infinite loop
  14. return req;
  15. }
  16. const accesstoken = sessionStorage.getItem("accesstoken")
  17. if (accesstoken){
  18. req.headers.Authorization = `Bearer ${accesstoken}`;
  19. //const {header,payload} = useJwt(accesstoken)
  20. let user = VueJwtDecode.decode(accesstoken);
  21. const isExpired = Date.now() >= ((user.exp * 1000) - 10000)
  22. console.log(isExpired)
  23. if (!isExpired) return req;
  24. requestArray.push(req);
  25. console.log("is expired");
  26. /* refreshing_token = refreshing_token ? refreshing_token : refresh_token();
  27. let res = await refreshing_token;
  28. refreshing_token = null;
  29. clearTimeout(myTimeout);*/
  30. if (!busy){
  31. busy = true;
  32. const refreshtoken = sessionStorage.getItem("refreshtoken")
  33. axios.post(baseURL + 'auth/refresh', {
  34. refresh_token : refreshtoken
  35. }).then((res) => {
  36. console.log(res);
  37. console.log("token refreshed : " + res.data.accesstoken);
  38. const authappstore = useAuthStore()
  39. authappstore.isAppOK = true;
  40. sessionStorage.setItem("accesstoken",res.data.accesstoken);
  41. sessionStorage.setItem("refreshtoken", res.data.refreshtoken);
  42. req.headers.Authorization = `Bearer ${res.data.accesstoken}`;
  43. if (requestArray.length !== 0) {
  44. requestArray.forEach(x => {
  45. try {
  46. console.log(x);
  47. axios(x)
  48. } catch (e) {
  49. console.log(e)
  50. }
  51. });
  52. requestArray = [];
  53. }
  54. }) .catch((err) => {
  55. const errStatus = err.statusCode || 500;
  56. const errMsg = err.message || 'Something went wrong';
  57. console.log(errMsg)
  58. }) .finally(() => {
  59. busy = false;
  60. });
  61. }
  62. }
  63. else {
  64. return req
  65. }
  66. })
  67. export default axios;

字符串
我不知道该怎么做?

laximzn5

laximzn51#

我只是提供了一个想法,你需要等待一个新的访问令牌当一个请求的访问令牌过期,并继续该请求(而不是推送到数组中),所以我们需要在请求拦截器中返回一个Promise,让请求处于等待状态,并且我们需要创建一个CustomEvent,当getRefreshToken的请求完成时,CustomEvent被触发,Promise此时会被解析,请求将继续。

  1. import axios from 'axios';
  2. import {
  3. useAuthStore
  4. } from "@/stores/Authentication/AppAuthStore.js";
  5. import VueJwtDecode from 'vue-jwt-decode';
  6. axios.defaults.baseURL =
  7. import.meta.env.VITE_API_ENDPOINT;
  8. axios.defaults.maxRedirects = 0;
  9. let refreshing_token = null;
  10. let myTimeout = null;
  11. let busy = false;
  12. const baseURL =
  13. import.meta.env.VITE_API_ENDPOINT;
  14. const getRefreshToken = new CustomEvent('getRefreshToken');
  15. axios.interceptors.request.use(async req => {
  16. if (req.url.endsWith("refresh")) {
  17. // if we are making a refresh token call, return it to prevent infinite loop
  18. return req;
  19. }
  20. const accesstoken = sessionStorage.getItem("accesstoken")
  21. if (accesstoken) {
  22. req.headers.Authorization = `Bearer ${accesstoken}`;
  23. //const {header,payload} = useJwt(accesstoken)
  24. let user = VueJwtDecode.decode(accesstoken);
  25. const isExpired = Date.now() >= ((user.exp * 1000) - 10000)
  26. console.log(isExpired)
  27. if (!isExpired) return req;
  28. return refresh(req)
  29. } else {
  30. return req
  31. }
  32. })
  33. function refresh(req) {
  34. if (!busy) {
  35. busy = true;
  36. const refreshtoken = sessionStorage.getItem("refreshtoken")
  37. axios.post(baseURL + 'auth/refresh', {
  38. refresh_token: refreshtoken
  39. }).then((res) => {
  40. console.log(res);
  41. console.log("token refreshed : " + res.data.accesstoken);
  42. const authappstore = useAuthStore()
  43. authappstore.isAppOK = true;
  44. sessionStorage.setItem("accesstoken", res.data.accesstoken);
  45. sessionStorage.setItem("refreshtoken", res.data.refreshtoken);
  46. window.dispatchEvent(getRefreshToken)
  47. }).catch((err) => {
  48. const errStatus = err.statusCode || 500;
  49. const errMsg = err.message || 'Something went wrong';
  50. console.log(errMsg)
  51. }).finally(() => {
  52. busy = false;
  53. });
  54. }
  55. return new Promise(res => {
  56. function send() {
  57. const accesstoken = sessionStorage.getItem("accesstoken");
  58. req.headers.Authorization = `Bearer ${accesstoken}`;
  59. res(req)
  60. window.removeEventListener('getRefreshToken', send)
  61. }
  62. window.addEventListener('getRefreshToken', send)
  63. })
  64. }

字符串

展开查看全部

相关问题