【问题标题】:Logout based on unauthorized API response基于未经授权的 API 响应注销
【发布时间】:2019-09-18 00:32:20
【问题描述】:

我已经创建了这样的 Rest API 助手。

class Api {
  final String _url = baseUrl + "api/";

  _logout() async {
    // EXIT ALL ONGOING PROCESSES HERE & NAVIGATE TO LOGOUT SCREEN
    await navigatorKey.currentState.pushReplacement(
      MaterialPageRoute(
        builder: (context) => Login(),
      ),
    );

    return {'success': false, 'error': 'Authentication failed!'};
  }

  Future get(url) async {
    // Getting token from sharedprefs
    String token = Prefs.prefs.getString("token");

    // Set authorization header
    Map<String, String> headers = {
        'accept': 'application/json',
        'authorization': 'Bearer ' + token;
    };

    return await http.get(_url + url, headers: headers).then((response) {
      if (response.statusCode == 200) {
        // Valid response
        return convert.jsonDecode(response.body);
      } else {
        // 401 Status code
        return _logout();
      }
    });
  }
}

然后在屏幕/视图中,我正在调用这样的 API。

@override
void initState() {
  super.initState();

  Api().get('getdata').then((response) {
      setState(() {
        _data = response;
      })
  });
}

对于有效/未过期的 API 令牌

对于成功的 api 响应,获取的数据将使用 setstate 方法在视图中更新。它工作得很好。

对于无效/过期的 API 令牌

对于无效令牌,API 将给出 401 状态码,API 助手将使用 _logout() 函数导航到登录屏幕。

在这里,它没有按预期工作。这里的应用程序推送到登录屏幕,但它给了我这样的错误。

如果您对不再出现在小部件树中的小部件(例如,其父小部件不再在其构建中包含该小部件)调用 State 对象的 setState(),则会发生此错误。当代码从计时器或动画回调中调用 setState() 时,可能会发生此错误。首选的解决方案是取消计时器或停止在 dispose() 回调中收听动画。另一种解决方案是在调用 setState() 之前检查该对象的“已安装”属性,以确保该对象仍在树中。

我的问题是,

这是基于 REST API 响应进行注销的正确方法吗?

编辑:

简单来说,每当我在 REST API 帮助程序中收到未经授权的响应时,我都想注销。

同样没有 API 助手,手动为每个地方编写 if-else 语句是不可行的。

【问题讨论】:

  • 问题在于,基本上从有状态小部件中调用 api 在颤动中是不正确的,因为您的小部件可以被释放,然后您丢失了响应,因此您必须检查小部件是否已被释放。 docs.flutter.io/flutter/widgets/FutureBuilder-class.html 使用futurebuilder根据缓存的api响应自动注销用户

标签: dart flutter


【解决方案1】:

我认为你应该使用 scoped_model 来管理你的应用状态

查看软件包以获取有关其工作原理的更多信息 Link

【讨论】:

  • 谢谢,我会尝试对 scoped_model 做同样的事情。
  • 状态管理也有同样的问题。还检查了flutter_block插件。
  • 您可以将其包装在根小部件中并检查构建方法的登录状态
【解决方案2】:

身份验证 过程失败时,您可以做的就是导航登录屏幕 >

使用它来关闭所有先前的屏幕并让用户登录 i。 因此,当用户按下后退按钮时,它将关闭应用程序

Navigator.of(context)
        .pushNamedAndRemoveUntil('/login', (Route<dynamic> route) => false);

而且我认为你的 API 应该像 json {status: 'success'} 一样传递更多 info检查响应和正文内容以验证登录是否成功

【讨论】:

  • 它仍然给我 setState 错误:“setState() 在 dispose() 之后调用”。我认为,状态管理会解决这个问题。
  • @Hiren 当您离开特定路线时,您不必调用 set state 而且如果您使用范围模型,请不要调用 set state 而是调用模型类点 notifychanges()
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-06-06
  • 2011-10-14
  • 1970-01-01
相关资源
最近更新 更多