【问题标题】:Flutter redirect when encountered http 401遇到 http 401 时颤振重定向
【发布时间】:2019-11-25 05:12:50
【问题描述】:

我现在有这样的导航:

main > app > account > address

现在我遇到问题,如果用户获取地址并且他们的会话过期,我该如何将他们重定向回登录页面?还是新手,找不到解决方案如何将未经身份验证的状态发送到main,以便它可以重定向它。

我正在使用 dio 和 MobX 包。

 dio.interceptors
        .add(InterceptorsWrapper(onRequest: (RequestOptions options) async {
      SharedPreferences prefs = await SharedPreferences.getInstance();

      String token = prefs.getString('access_token');

      if (token != null) {
        options.headers['Authorization'] = 'Bearer $token';
      }

      options.headers['Accept'] = 'application/json';

      return options; //continue
    }, onResponse: (Response response) {
      final int statusCode = response.statusCode;
      var results = {};

      if (statusCode == 200 || statusCode == 201 || statusCode == 204) {
        final dynamic decodeResponse = this.decodeResponse(response);
        bool responseIsList = decodeResponse is List;

        if (!responseIsList && decodeResponse['token'] != null) {
          final token = decodeResponse['token'];
          setAuthorizationToken(token['access_token'], token['refresh_token']);
        }

        if (responseIsList) {
          return decodeResponse;
        } else {
          final resultToAdd = decodeResponse;

          results.addAll(resultToAdd);

          return results;
        }
      }

      return response;
    }, onError: (DioError e) async {
      final r = e.response;
      if (r.statusCode == 401) {
        AuthStore().unauthorize(prefs: _sharedPreferences);
      }

      if (r != null) {
        return {"has_error": true, ...r.data};
      }
      // Do something with response error
      return e;
    }));

我已尝试将 Observer 放在我的 main.dart 上以继续检查状态

@override
Widget build(BuildContext context) {
  return Observer(builder: (_) {

  if (store.statusAuth == 401) {
    Navigator.pushReplacementNamed(context, '/'); // this is error
  } 


  // other material app function
});

有什么办法吗?

我现在唯一能想到的解决方案是在每次调用 API 时检查(每个商店)。如果 401 会自动将其发送回登录页面。但是这种方法会非常多余。

【问题讨论】:

    标签: flutter


    【解决方案1】:

    我也有同样的问题。为了解决这个问题,我们需要一个没有 contextNavigation 才能在 interceptors 上导航。 Api 服务在 MaterialApp 之前初始化。 MaterialApp 允许传递顶部导航器的 navigatorKey。

    我在定义 apiservice 的拦截器时创建 GlobalKey 并将其用于返回 MaterialApp。

      final GlobalKey<NavigatorState> navigator;//Create a key for navigator
    

    并创建 apiService

    void _configAuthApiService() {
        ...
        if (error.response?.statusCode == 401) {
            navigator.currentState.pushReplacementNamed('/login');
        }
        ...
    }
    

    创建材质应用时:

    MaterialApp(
        ...
        navigatorKey: navigator,
        ...
    )
    

    【讨论】:

    • 如何在_configAuthApiService 中获取navigator
    • 我把 navigator 放到 ApiService 的构造函数中。
    • 谢谢,但没有帮助我。
    猜你喜欢
    • 2020-08-08
    • 2022-06-28
    • 1970-01-01
    • 1970-01-01
    • 2022-11-07
    • 2019-04-17
    • 1970-01-01
    • 2022-07-31
    • 2023-03-23
    相关资源
    最近更新 更多