请求重试最佳实践



我正在使用Flutter、GraphQL和带有NodeJS API的Firebase构建应用程序。在我的应用程序中,我实现了Firebase身份验证和令牌刷新,我的nodejs api对其进行了验证。我的令牌刷新间隔为3500秒(其中令牌有效期为3600秒(。然而,在某些情况下(我不知道为什么(,在我让应用程序打开半天后,我开始收到来自令牌验证的消息,我必须刷新令牌(不知道如何捕获它,因为在测试间隔刷新时效果很好(。。。

那么,在应用程序中刷新令牌最常见的方法是什么呢?也许应用程序会在不活动和刷新计时器停止时自动进行hybernate?如果是,那么我应该用什么事件来捕捉应用程序再次激活?

感谢

p.s.经过一些研究,我意识到令牌刷新间隔有什么问题——而手机处于活动状态,刷新间隔工作正常。如果我锁定手机屏幕时间间隔停止。再次打电话后,时间间隔从开始再次开始。这里主要的问题发生了-由于FB令牌的有效期为1小时,所以有99%的iser会打开他的手机屏幕,在他再次打开后,计时器将从头开始-但令牌将过期。。。

你知道在手机/应用程序再次激活后会触发哪些颤动事件吗?

任何OAuth客户端中的一条绝对黄金法则是实现以下行为:

  • 如果您从API获得401
  • 尝试获取新的访问令牌-仅一次
  • 重试API调用-仅一次

我的一些示例Android代码可以做到这一点。

然而,无论使用何种类型的客户端或技术,该要求都是通用的。在我自己的应用程序中,我从不读取代币到期信息,只是让401发生。这是一个有弹性的解决方案,因为401的发生有很多原因。

我建议首先关注需求,其次关注技术

Firebase Auth将每小时或根据需要自动刷新用户的ID令牌。你不必为此编写任何代码。

Android、iOS和JS库都提供了一种方法来监听ID令牌的更改,但Flutter显然没有公开这个API。但是,您仍然可以定期调用getIdToken(false(来获取当前的ID令牌。只是不要坚持太久。

所以经过研究,我最终用两个步骤解决了这个问题。

  1. 使用以下代码初始化定期令牌刷新:

    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();
    }
    }
    
  • 最新更新