返回

防止代币过期的订阅发布者模式

前端

简介

在构建现代分布式系统时,身份验证和授权至关重要。JSON Web 令牌 (JWT) 已成为实现这些功能的流行机制。然而,JWT 具有有限的生存期,需要定期刷新以保持会话活动状态。

当处理需要多个 API 请求的应用程序时,处理令牌过期可能会很棘手。如果其中一个请求导致令牌过期,则必须重新发出所有请求,这可能会导致延迟和用户体验不佳。

为了解决这个问题,我们可以使用订阅发布者模式。该模式提供了一种松耦合的机制,用于在发布者和多个订阅者之间异步通信。

订阅发布者模式的实现

我们的订阅发布者模式包含两个主要组件:

  • 发布者: 当令牌快到期时,发布者负责生成新令牌并通知订阅者。
  • 订阅者: 这些组件订阅发布者的更新,并在收到新令牌时更新其本地副本。

使用 Promise 协调请求

为了协调多个 API 请求,我们将使用 Promise。Promise 是 JavaScript 中的一种对象,表示异步操作的最终完成或失败。

我们可以创建以下 Promise 链:

getToken()
  .then(token => {
    makeRequest1(token);
    return token;
  })
  .then(token => {
    makeRequest2(token);
    return token;
  })
  .then(token => {
    makeRequest3(token);
  })
  .catch(error => {
    // 处理令牌过期或其他错误
  });

此 Promise 链确保仅在成功获取令牌后才发出后续请求。如果令牌过期,getToken() Promise 将被拒绝,导致整个链条失败。这使我们能够优雅地处理错误并重试请求。

代码示例

以下是使用订阅发布者模式和 Promise 处理令牌过期的示例代码:

// 发布者
const publisher = new Publisher();

// 创建 JWT 刷新函数
const refreshJwt = async () => {
  const newToken = await getAccessToken();
  publisher.publish(newToken);
};

// 创建订阅者
const subscriber = new Subscriber();
subscriber.subscribe(publisher, (token) => {
  // 更新令牌
  updateToken(token);
});

// 创建 API 请求函数
const makeApiCall = (token) => {
  // 使用令牌发出 API 请求
};

// 主函数
const main = async () => {
  // 获取初始令牌
  const token = await getAccessToken();
  
  // 设置刷新令牌计时器
  setInterval(refreshJwt, token.expires_in * 1000);

  // 发出 API 请求
  makeApiCall(token);
};

main();

结论

通过使用订阅发布者模式和 Promise,我们可以有效地处理令牌过期问题,同时避免在需要多个 API 请求的应用程序中出现并发问题。这可以显着提高应用程序的可靠性和用户体验。