在 Ktor 客户端中重新触发 loadTokens 的正确方法

gpu*_*nto 14 kotlin ktor ktor-client

在我的移动应用程序中,我有一个单例 Ktor HttpClient,其不记名身份验证配置如下:

\n
HttpClient(\xe2\x80\xa6) {\n    install(Auth) {\n        bearer {\n            sendWithoutRequest { requestBuilder -> some condition }\n            loadTokens(tokensStorage::getTokens)\n            refreshTokens {\n                performTokenRefresh(oldTokens.refreshToken)\n            }\n        }\n    }\n}\n
Run Code Online (Sandbox Code Playgroud)\n

现在考虑以下流程:

\n
    \n
  1. 用户打开应用程序,而 my 中存储的令牌tokenStorage无效。
  2. \n
  3. 从中加载HttpClient令牌tokenStorage,请求失败并返回 401。
  4. \n
  5. 尝试HttpClient执行刷新,但也失败,因为刷新令牌无效。
  6. \n
  7. 用户被重定向到登录页面,登录,新的有效令牌存储在tokenStorage.
  8. \n
  9. 现在,用户可以从应用程序重试第 2-3 点中失败的呼叫。然而,这将永远失败,直到应用程序关闭,因为它HttpClient不再尝试调用loadTokens。确实,从源代码来看,loadTokens只被调用一次,然后就不会再被调用。
  10. \n
\n

我找到了解决该问题的几种方法。

\n

第一个是手动BearerAuthProviderHttpClient自己清除令牌,如以下代码片段所示,但这似乎是一种黑客解决方法:

\n
httpClient.plugin(Auth).providers\n    .filterIsInstance<BearerAuthProvider>()\n    .first().clearToken()\n
Run Code Online (Sandbox Code Playgroud)\n

tokenStorage另一种方法是从 my in手动加载当前令牌refreshToken并忽略传入的内容this@refreshTokens.oldTokens

\n
refreshTokens {\n    val currentRefreshToken = tokenStorage.getTokens().refreshToken\n    performTokenRefresh(currentRefreshToken)\n}\n
Run Code Online (Sandbox Code Playgroud)\n

然而,这意味着客户端将对刷新 API 进行不必要的调用,同时已经拥有有效的令牌对(从登录中获取)。

\n

所以我的问题是:有没有更干净的方法来处理这种情况?我是否滥用了 Ktor?

\n