在 Flutter 应用程序过期后将问题发送到 Azure AAD 令牌中以静默方式刷新

问题描述 投票:0回答:1

我正在尝试使用 AAD 登录我的移动应用程序,并且运行良好。但是过了一段时间,比如 1 小时令牌过期了,所以我尝试刷新,但我总是得到过期的令牌作为响应,

如果我注销并登录,那么一切都按照流程正常工作。

所以不确定在哪里遇到问题......

我现在正在使用 https://pub.dev/packages/aad_oauth 插件。

但作为替代方案,我尝试使用 https://pub.dev/packages/flutter_aad_oauth 但进入其中,将问题放入重定向 URL,这样就不用花更多时间来弄清楚。

然后我找到了一些很好的链接https://www.hasaltaiar.com.au/how-to-best-handle-aad-access-tokens-in-native-mobile-apps/

但不知道如何在没有插件的情况下使用 Flutter

这里有人有这方面的经验或者知道如何解决这个问题吗?

authentication azure-active-directory jwt access-token refresh-token
1个回答
0
投票

静默刷新可以在flutter中使用拦截器。仔细阅读代码中的注释。

主要部分是您可以在拦截器中检查令牌是否过期,然后进行静默登录并更新访问令牌和标头。

 dio.interceptors.add(
      InterceptorsWrapper(
        onRequest: (
          RequestOptions requestOptions,
          RequestInterceptorHandler handler,
        ) async {
          //mentioned below
          await getAccessToken(
            false,
          );
          
          //JwtDecoder for check if current token is expired
          final accessTokenHasExpired = JwtDecoder.isExpired(accessToken ?? "");
          if (accessTokenHasExpired) {
            //oauth instance
            final AadOAuth oauth = AadOAuth(AppConfigurations.config);
            
            //silent login with refreshIfAvailable true
            final result = await oauth.login(refreshIfAvailable: true);

            result.fold(
              (failure) => null,
              (token) async {
                
                //get new access token
                final accessToken = await oauth.getAccessToken();

               
                //update new access token
                await AppLocalStorage().setStringPrefValue(
                  key: AppConstants.accessToken,
                  value: accessToken ?? "",
                );

               //update headers
                requestOptions.headers.addAll({
                  'Content-type': 'application/json',
                  'Charset': 'utf-8',
                  'Accept': 'application/json',
                  'Authorization': 'Bearer $accessToken',
                });
              },
            );
          } else {
            requestOptions.headers.addAll({
              'Content-type': 'application/json',
              'Charset': 'utf-8',
              'Accept': 'application/json',
              'Authorization': 'Bearer $accessToken',
            });
          }
          handler.next(requestOptions);
        },
        onResponse: (
          Response<dynamic> response,
          ResponseInterceptorHandler handler,
        ) {
          handler.next(response);
        },
        onError: (
          DioException error,
          ErrorInterceptorHandler handler,
        ) async {
          handler.next(error);
        },
      ),
    );
    dio.interceptors.add(
      LogInterceptor(
        request: true,
        requestBody: true,
        error: true,
        requestHeader: true,
        responseBody: true,
        responseHeader: true,
      ),
    );


Future<void> getAccessToken(
    bool isGraph,
  ) async {
    if (isGraph) {
      accessTokenGraph = await AppLocalStorage()
              .getStringPrefValue(key: AppConstants.accessTokenGraph) ??
          "";
    } else {
      accessToken = await AppLocalStorage()
              .getStringPrefValue(key: AppConstants.accessToken) ??
          "";
    }
  }

© www.soinside.com 2019 - 2024. All rights reserved.