我的React应用程序使用Axios进行API请求。
Axios通过请求拦截器将访问令牌添加到每个API请求的头部。我想在发送当前请求之前检查到期日期。如果访问令牌到期,Axios应该进行刷新操作,更改存储中的访问令牌,然后使用新令牌从应用程序发出第一个请求。
对于刷新和其他API操作,我使用Redux Toolkit Slices。
我没有任何情况下刷新请求拦截器工作正常。我找到了解决方案与响应拦截器,但它不是我的方式。
如何在请求拦截器中刷新访问令牌?
这是我的Axios示例:
export const createAPI = (): AxiosInstance => {
const api = axios.create({
baseURL: getAPIURL(),
timeout: REQUEST_TIMEOUT,
withCredentials: true
});
api.interceptors.request.use(
async (config: InternalAxiosRequestConfig) => {
const accessToken = store.getState().user.accessToken;
if (accessToken && config.headers) {
config.headers['authorization'] = `Bearer ${accessToken}`;
}
// todo Check access token and refresh if it expired
if (!config.data) return config;
config.data = adaptFromClientToServer(config.data);
return config;
}
);
api.interceptors.response.use(
(response) => {
if (!response.data) return response;
response.data = adaptFromServerToClient(response.data);
return response;
}
);
return api;
};
字符串
4条答案
按热度按时间sz81bmfz1#
在请求拦截器中检查token是否过期时,需要注意的是,如果token在前端没有过期,并不一定意味着它在后端仍然有效。前端和后端系统之间可能存在时间延迟。为了确保token的有效性,建议在请求拦截器和响应拦截器上同时实现解决方案。
此外,在API URL为公共URL的场景中,如果不需要令牌,则无需发起令牌刷新。在这种情况下,跳过刷新令牌API调用是有效的。这种方法有助于优化令牌管理,避免在令牌未使用时执行不必要的刷新操作。
不推荐仅依靠请求拦截器来检查刷新令牌。
gwbalxhn2#
你的API模块看起来在正确的轨道上, Package 常见的API逻辑(随着时间的推移变得越来越复杂),并简化视图和视图模型中的代码。我的答案是关于可移植和弹性API客户端的设计选择。
令牌响应
令牌响应总是包含
expires_in
字段。还请注意,访问令牌可能是不透明/不可读令牌,而不是JWT:字符串
刷新选择
前端可以保留
expires_in
字段和发布时间,并通过以下方法之一管理刷新:1.如果当前时间指示令牌即将到期,则在API请求之前进行刷新
1.当令牌接近到期时,刷新后台计时器
1.如果API返回401状态,则执行刷新
弹性
访问令牌可能会因过期以外的原因而失败。其中一个原因可能是吊销。在某些设置中,它可能是由基础设施事件(如令牌签名密钥续订或负载平衡故障转移)引起的。因此,请始终执行选项3(主要行为),并根据您的偏好将其与选项1或2(优化)结合使用。
一致性
如果多个视图同时调用API,则令牌刷新应该同步。这导致了一种设计,即放弃promise,但只在第一个视图上发出刷新请求,然后使用新的访问令牌恢复所有API请求。可以使用这样的代码:
型
更多信息
有关这些概念的更多信息,请参阅我的这些资源。我的代码不使用Axios拦截器,但令牌刷新代码很容易集成到您的代码中。
8e2ybdfx3#
这就是你的处理方式
字符串
rggaifut4#
您可以使用
jose
(或类似的)库从令牌中提取exp
声明。它是一个数字日期,您可以轻松地将其与当前时间进行比较(减去几秒以考虑潜在的延迟)。使用Promise
处理多个请求字符串