请求重试最佳实践
Request retry best practices
我正在使用 Flutter、GraphQL 和 Firebase 以及 NodeJS 构建应用程序 API。
在我的应用程序中,我实现了 Firebase 身份验证和令牌刷新,我的 nodejs api 对其进行了验证。
我的令牌刷新间隔为 3500 秒(其中令牌的有效期为 3600 秒)。但是在某些情况下(我不知道为什么)在我将应用程序打开半天后,我开始收到来自令牌验证的消息,我必须刷新令牌(不知道如何捕获它,因为在测试间隔刷新时只是工作很好)...
那么在应用程序中刷新令牌最常见的方式是什么?也许应用程序会在非活动状态和刷新计时器停止时自动休眠?如果是 - 那么我应该使用什么事件来捕获应用程序再次激活?
谢谢
p.s。经过一些研究,我意识到令牌刷新间隔有什么问题 - 而 phone 是活动刷新间隔工作正常。如果我锁定 phones 屏幕时间间隔停止。在 oepning phone 之后,时间间隔再次从 BEGINNING 开始。这里出现了主要问题——因为 FB 令牌的有效期为 1 小时,所以有 99% 的人会打开他的 phone 屏幕,并且在他再次打开它之后,计时器将从头开始 - 但令牌将过期.. .
您知道 phone/应用程序再次激活后触发的任何 flutter 事件吗?
Firebase Auth 将每小时或根据需要自动刷新用户的 ID 令牌。您不必为此编写任何代码。
Android、iOS、JS库都提供了监听ID token变化的方法,但Flutter显然没有暴露这个API。但是,您仍然可以定期调用 getIdToken(false) 来获取当前 ID 令牌。只是不要坚持太久。
所以经过研究,我最终用 2 个步骤解决了它。
使用此代码初始化定期令牌刷新:
void _handleAuthStateChanged(FirebaseUser e) async {
if (e == null) {
_authentication = null;
} else {
/// Get token
final firebaseToken = await e.getIdToken(refresh: true);
/// Setup token refresh
firebaseToken.expirationTime.asFuture(() async {
var user = await FirebaseAuth.instance.currentUser();
_handleAuthStateChanged(user);
});
extension DateTimeFutureX on DateTime {
Future<T> asFuture<T>([FutureOr<T> Function() computation]) async {
final difference = this.difference(DateTime.now());
return Future.delayed(difference, computation);
}
}
并在 main.dart
中恢复应用程序时重新获取令牌
@override
Future<void> didChangeAppLifecycleState(AppLifecycleState state) async {
super.didChangeAppLifecycleState(state);
if (state == AppLifecycleState.resumed) {
await _authService.refreshToken();
}
}
任何 OAuth 客户端的绝对黄金法则是实现以下行为:
- 如果您从 API
收到 401
- 尝试获取新的访问令牌 - 仅一次
- 重试 API 呼叫 - 仅一次
Some sample Android code of mine that does this.
但无论使用何种客户端类型或技术,该要求都是通用的。在我自己的应用程序中,我从不读取令牌过期时间,只是让 401 发生。这是一个有弹性的解决方案,因为 401 的发生可能有多种原因。
我建议首先关注需求,其次关注技术
我正在使用 Flutter、GraphQL 和 Firebase 以及 NodeJS 构建应用程序 API。 在我的应用程序中,我实现了 Firebase 身份验证和令牌刷新,我的 nodejs api 对其进行了验证。 我的令牌刷新间隔为 3500 秒(其中令牌的有效期为 3600 秒)。但是在某些情况下(我不知道为什么)在我将应用程序打开半天后,我开始收到来自令牌验证的消息,我必须刷新令牌(不知道如何捕获它,因为在测试间隔刷新时只是工作很好)...
那么在应用程序中刷新令牌最常见的方式是什么?也许应用程序会在非活动状态和刷新计时器停止时自动休眠?如果是 - 那么我应该使用什么事件来捕获应用程序再次激活?
谢谢
p.s。经过一些研究,我意识到令牌刷新间隔有什么问题 - 而 phone 是活动刷新间隔工作正常。如果我锁定 phones 屏幕时间间隔停止。在 oepning phone 之后,时间间隔再次从 BEGINNING 开始。这里出现了主要问题——因为 FB 令牌的有效期为 1 小时,所以有 99% 的人会打开他的 phone 屏幕,并且在他再次打开它之后,计时器将从头开始 - 但令牌将过期.. .
您知道 phone/应用程序再次激活后触发的任何 flutter 事件吗?
Firebase Auth 将每小时或根据需要自动刷新用户的 ID 令牌。您不必为此编写任何代码。
Android、iOS、JS库都提供了监听ID token变化的方法,但Flutter显然没有暴露这个API。但是,您仍然可以定期调用 getIdToken(false) 来获取当前 ID 令牌。只是不要坚持太久。
所以经过研究,我最终用 2 个步骤解决了它。
使用此代码初始化定期令牌刷新:
void _handleAuthStateChanged(FirebaseUser e) async { if (e == null) { _authentication = null; } else { /// Get token final firebaseToken = await e.getIdToken(refresh: true); /// Setup token refresh firebaseToken.expirationTime.asFuture(() async { var user = await FirebaseAuth.instance.currentUser(); _handleAuthStateChanged(user); }); extension DateTimeFutureX on DateTime { Future<T> asFuture<T>([FutureOr<T> Function() computation]) async { final difference = this.difference(DateTime.now()); return Future.delayed(difference, computation); } }
并在 main.dart
中恢复应用程序时重新获取令牌@override Future<void> didChangeAppLifecycleState(AppLifecycleState state) async { super.didChangeAppLifecycleState(state); if (state == AppLifecycleState.resumed) { await _authService.refreshToken(); } }
任何 OAuth 客户端的绝对黄金法则是实现以下行为:
- 如果您从 API 收到 401
- 尝试获取新的访问令牌 - 仅一次
- 重试 API 呼叫 - 仅一次
Some sample Android code of mine that does this.
但无论使用何种客户端类型或技术,该要求都是通用的。在我自己的应用程序中,我从不读取令牌过期时间,只是让 401 发生。这是一个有弹性的解决方案,因为 401 的发生可能有多种原因。
我建议首先关注需求,其次关注技术