【问题标题】:Axios interceptor expiration timeaxios拦截器过期时间
【发布时间】:2021-05-20 19:28:55
【问题描述】:

下面我将发布我的 AXIOS 代码。当我启动应用程序(Vue js)时首先发生的是它打开登录页面,当我输入用户名/密码时,我在本地存储中设置令牌并刷新令牌。这很好用,我可以进行其他需要令牌的 api 调用。问题在到期时(登录后 3 分钟内)发生,进入无限循环。另外问题是我不知道如何检查刷新令牌的到期时间,因为我无法使用我编写的这个函数对其进行解码。

访问令牌:

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIyIiwianRpIjoiMTg4YjQ0NDg2MzdmMmJhYWRkMDE1MmU5OWRhNGIwMWYxMzgxMzVjY2Q5YjA2NmRlM2M4YjFkZjk4ODE1ZGZmNGZhOGE2ODQ2YWI4ZjY1YjkiLCJpYXQiOjE2MjE1MzcxOTAuNjg5MjgzLCJuYmYiOjE2MjE1MzcxOTAuNjg5Mjg2LCJleHAiOjE2MjE1MzczNzAuNjc3NDM3LCJzdWIiOiIyIiwic2NvcGVzIjpbXX0.U5lNHetMq6vEnUKwxlJ9sa9lU6ahj-lDlxjWFdaTuXaGCcmx8zb917OSKkZa1g8PA3NArC6nMVbWfbD44DXLF3I6UFFXAYNncuH8kAngIh-XyRhUgr3MDOR04dCb02Khchs30QnbznHFvox1wtTXLEIT2wzdGI0_GGQot3ZFvxBfukRVt64uqC7GrVxcpoZXV2LXY7LxkZXoEd88QFcjfWWw_RC1fyU7gNaGxF4xml5CyJGZOcM1S-1QlBsXE-HE5qeJPZilxOJLHvxSYo-HFTbl7u0WNlryyCAxJqoeMHIqmHrEmZX261IdMFdQ7sl9YP-rXtg5hY_SDVoaE-KjHThltKvPkV_XeWxWQ3KqCDqm7UMZyxkWzEMglE4Ym8hvNsgUIlZMVeKCuYkQ2Vri-X2whttaVwM4-pJPbAqJURYu2WRDWgBbIWWkXkw4GLUFTDIllOmIBESUjba_L3x2dHrce3PpBOBw8dYDPttdqch6t_J7vBsRUu8-DcHDzxnVu6vBYmQA-TAlI9yN7gOgn_gMDMq6FhitKuQ9KghACJmTjqB-_BbxAI3pWwAuPeAas7uB9ugzpScKPPZtThoI08wQ8pT7Xz8JvZTEharzUHcldu2rIlUCif6l-rtszIQNYcCfWFMBVP9HFRSgCcEtgl3L5SPfQGW0Ytc2P_ED4HE P>

刷新令牌:

def502009a8ebae0e2d2d18b541daa39725ed826115ce9612db43e399b3edc7fe7d08950e5972b8c13faa8846962fb4a027a95a5cdefcdb526051644a1031c909ee6ad1cbc421aa12d0a096728dff99e8c72aef8e7e527824287274cee8d702d20e7468985d5d648c990df99990c283b490bb33d97cf2ecfaf176e6ecd2259db183d95d7bdd664600319d6af36e463e777e01cdd364cdbf146d10ea9a58a1ba5b01adb98ac7ffb27ebfd10cb62f79d1bcb7bf13c3adc1fe70f9de554bc98258ac8071d46a1cc51812140fae06291868016e97b39bb31b8a749a4ed2daa78f53e66256351d3aada01f5bb7ffcc5d4f8494cb0116b9816e92ba614e78dff8730b7e81b22049b73a69956a55daeec3b53c4a87f34280af1451cf67e81f804346fa1f121788af98becedb896991c8349e87eace91b73019381cc8550160742e3141ea7ef3eb0a71333496489c3e43c47fb18c076d2a9950ffe6dc6138bea1f7cd8cbf3 P>

它们是不同的,当我解码访问令牌时,我得到一个对象,该对象具有此键 "exp":1621533539.9695,它是过期时间,但不适用于刷新令牌。

有什么想法吗?

export const API = axios.create({
  baseURL: BASE_URL,
  withCredentials: false,
  headers: {
    Accept: "*/*",
    "Access-Control-Allow-Origin": "*",
  },
});


// CHECK IF TOKEN IS EXPIRED (DECODE TOKEN)
function isTokenExpired(token) {
  const base64Url = token.split(".")[1];
  const base64 = base64Url.replace(/-/g, "+").replace(/_/g, "/");
  const jsonPayload = decodeURIComponent(
    atob(base64)
      .split("")
      .map(function (c) {
        return "%" + ("00" + c.charCodeAt(0).toString(16)).slice(-2);
      })
      .join("")
  );
  const data = JSON.parse(jsonPayload);
  const expirationDate = data.exp;
  const currentDate = new Date().getTime() / 1000;
  return currentDate >= expirationDate;
}


API.interceptors.request.use(
  async (config) => {
    let token = localStorage.getItem("accessToken");
    let refreshToken = localStorage.getItem("refreshToken");

    //if refresh token is expired we logout and return early
    // if (refreshToken) {
    //   const isExpired = isTokenExpired(refreshToken);
    //   if (isExpired) {
    //     localStorage.setItem("accessToken", "");
    //     localStorage.setItem("refreshToken", "");
    //     router.push({ path: "/login" });
    //   }
    //   return config;
    // }

    // if token is expired we refresh the token
    if (token) {
      const isExpired = isTokenExpired(token);
      if (isExpired) {
        const data = await API.post("/token", {
          grant_type: "refresh_token",
          refresh_token: refreshToken,
        });
        if (data) {
          token = data.access_token;
          localStorage.setItem("accessToken", data.data.access_token);
          localStorage.setItem("refreshToken", data.data.refresh_token);
        }
      }
      config.headers.Authorization = `Bearer ${token}`;
    }
    return config;
  },
  (error) => Promise.reject(error)
);



//CHECK AFTER REQUEST IF RESPONSE IS 401
API.interceptors.response.use(
  (response) => response,
  async (error) => {
    let refreshToken = localStorage.getItem("refreshToken");

    if (error.response?.status && error.response?.status === 401) {
      const data = await API.post("/token", {
        grant_type: "refresh_token",
        refresh_token: refreshToken,
      });
      if (data) {
        localStorage.setItem("accessToken", data.data.access_token);
        localStorage.setItem("refreshToken", data.data.refresh_token);
        error.config.headers.Authorization = "Bearer " + data.access_token;
        return API.request(error.config);
      }
    }
    throw error.response;
  }
);

【问题讨论】:

    标签: javascript api rest axios endpoint


    【解决方案1】:

    刷新令牌不附带到期日期。 您需要尝试使用它获取新令牌。如果无效,您的 API 会告诉您,然后您需要将您的用户发送回登录页面。

    我想你知道刷新令牌流程,但我还是把它留在这里:

    1. 检查您的 localStorage 中是否有令牌和刷新令牌。
    2. 拥有它们后,检查令牌是否已过期。
    3. 如果过期,你需要将刷新令牌发送到你的api。
    4. API 将为您提供另一个令牌和 refreshToken,存储它们并继续发出请求。
    5. 如果 API 拒绝 refreshToken,请将您的用户发送到登录页面。

    如果您需要,我有一个完整的 refreshToken 和重新尝试请求的示例。

    每次您的令牌过期时,您都需要执行刷新令牌过程。

    【讨论】:

    • 你能给我一个例子吗?我仍在为此苦苦挣扎:/
    猜你喜欢
    • 1970-01-01
    • 2018-01-20
    • 2018-11-27
    • 2022-11-09
    • 1970-01-01
    • 2019-06-26
    • 2020-07-26
    • 2019-04-20
    • 2023-04-06
    相关资源
    最近更新 更多