在我的应用程序中,我有一个标记刷新端点/refresh
,它在cookie中设置新的JWT刷新标记,并将新的JWT访问标记作为json发送回去。
由于访问令牌在5分钟后过期,因此我需要实现一个后台刷新逻辑,以便在访问令牌过期时启动。
目前我正在做的是通过RTK Query
调用api,如果api拒绝查询,我就调用refreshTokens
变体。
我需要把这个逻辑放在所有的api查询中,如下所示:
updateProfile(body)
.unwrap()
.catch((error) => {
if (error && error.status === 403) {
refreshTokens(null); // RTK Query Mutation
updateProfile(body); // RTK Query Mutation
}
});
这样做似乎是代码的重复,因为它需要实现到所有对api的调用。
我想知道是否有一个全局解决方案可以在查询被拒绝时自动调用刷新令牌端点。
3条答案
按热度按时间d8tt03nd1#
嗨,我已经做了一些与您所做的类似的事情,并且不需要对每个API调用重复代码,
我已经创建了我自己的fetch函数,它将接收两个参数,一个是调用fetch函数的函数,另一个是调用刷新令牌的函数。
也许您可以使用从错误消息中获得的返回信息来重构它,以便以更好的方式构建它,或者将它构建为中间件...
flvlnr442#
注意:此解决方案在提取失败后自动刷新令牌,但不会自动重新提取最初失败的查询。因此,它仍然会导致代码重复。
这是我目前为止解决的方法:
1.在this doc的基础上创建了一个中间件来捕获宏级别的授权错误。它捕获授权错误并调用刷新JWT的突变,而不使用in this doc中解释的React钩子。此外,在RTK查询中间件之前附加错误处理中间件也很重要。
1.在我们通过中间件获得新的令牌后,我们再次调用
try/catch
块中的初始变异“无React钩子”。到目前为止,它的工作正如我所希望的那样。我唯一关心的是需要捕捉所有突变上的错误,并再次调用突变。如果有人有任何想法来处理它的全球性以及我会很感兴趣。
cpjpxq1n3#
在我最初的解决方案中,如果访问令牌过期,我可以重新获取JWT,但我无法为所有端点自动重新获取初始失败的查询。因此,我不得不为所有端点编写try-catch块。我不想编辑最初的答案,以免使解决方案看起来复杂,这也是一个有效的答案。
这是最终的解决方案,Redux RTK全局捕获授权错误并刷新JWT,然后自动重新获取初始失败的查询。
与我最初的答案相同的中间件,但这次
refreshTokens
不是一个突变,而是一个查询。1.我们通过
.invalidateTags
方法重新触发令牌刷新1.我们从
action.meta
获取被拒绝查询的 meta数据,并将其保存到存储中,以便在刷新令牌后重新生成失败的查询。然后,我们使用RTK查询的
onQueryStarted
方法等待令牌刷新完成:await queryFulfilled
确保令牌被刷新。1.通过
const { endpointName, originalArgs } = rejectedAction;
从存储中获取 meta数据1.并重新生成初始查询。
多亏了这个流程,Redux RTK Query可以捕获所有失败的查询,刷新JWT,并自动重新获取失败的查询。