遇到HTTP 401时颤振重定向

时间:2019-07-16 12:52:19

标签: flutter

我现在有这样的导航:

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会自动将其发送回登录页面。但是这种方法将非常多余。

1 个答案:

答案 0 :(得分:0)

我有同样的问题。要解决此问题,我们需要一个没有上下文 Navigation (导航),才能在拦截器上导航。 在MaterialApp之前初始化Api服务。允许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,
    ...
)