localStorage 在使用 Promise 设置时获得旧值

localStorage gets old value when setting it with a Promise

我正在使用 axios 向我的 API 发出请求,我在其中获取个人资料详细信息。

  getProfile(success, error) {
         return axios
          .get("/auth/me/", { headers: this.authHeader() })
          .then(resp => {
                if (resp.status === 200) {
                    success(resp.data)
                } ...and so on..
            })
    }

authHeader 函数基本上是 return 的 JWT 令牌,如果它已过期,则调用 refreshToken 函数即:

authHeader() {
      let token = loadToken()?.access_token // loadToken just loads from localStorage
      if (token ) {
        const epoch = new Date().getTime() / 1000
        const decodedJwt = jwt_decode(icpToken)
        if (decodedJwt.exp <= epoch) {
            this.refreshToken().then(() => {
                return { "Authorization": 'Bearer ' + loadToken()?.access_token } // When 
// this is resolved, shouldn't loadToken return the new value, and 
// with that, getProfile should continue with it?
            })
        }
        return { "Authorization": 'Bearer ' + loadToken()?.access_token }
      } else {
        return {};
      }
    }

refreshToken() {
    return axios
        .post("/auth/token/refresh/", {"refresh": loadToken()?.refresh_token})
        .then(resp => {
            if (resp.status === 200) {
                localStorage.setItem('token', JSON.stringify({
                    ...loadToken(),
                    "access_token": resp.data["access"]
                }))
            }
        })
}

这个问题是 getProfile 函数变成了旧的 header,但我可以看到它在 localStorage 中被 refreshToken 改变了。据我了解,refreshToken 应该 return 一个 PromiseauthHeader,在解决后,应该调用 .then() 和 return 新的 header 使用新令牌。

refreshToken 是异步的,但是你是同步使用的。您正在以同步方式调用 this.authHeader(),所以我认为您需要这样调用它:

async getProfile(success, error) {
  return this.authHeader()
  .then((headers) => {
    return axios.get("/auth/me/", { headers }).then((resp) => {
      if (resp.status === 200) {
        success(resp.data);
      } // ...and so on..
    });
  })
}

此外,您需要将 authHeader 更新为 return 承诺:

async authHeader() {
  let token = loadToken()?.access_token; // loadToken just loads from localStorage
  if (token) {
    const epoch = new Date().getTime() / 1000;
    const decodedJwt = jwt_decode(icpToken);
    if (decodedJwt.exp <= epoch) {
      return this.refreshToken().then(() => {
        return { Authorization: "Bearer " + loadToken()?.access_token }; // When
        // this is resolved, shouldn't loadToken return the new value, and
        // with that, getProfile should continue with it?
      });
    }
    return { Authorization: "Bearer " + loadToken()?.access_token };
  } else {
    return {};
  }
}