繁体   English   中英

如果 Flutter API 响应未经授权,如何重定向到登录页面?

[英]How to redirect to a login page if Flutter API response is unauthorized?

我正在构建一个 Flutter 应用程序,它使用 Golang API 来获取数据。 如果 JWT 令牌无效,则 API 将返回 401 未授权。 如果响应状态为 401,如何在任何 API 调用上重定向到登录页面?

这是我的 flutter 代码:

main.dart

void main() async {

  WidgetsFlutterBinding.ensureInitialized();

  Provider.debugCheckInvalidValueType = null;

  AppLanguage appLanguage = AppLanguage();
  
  await appLanguage.fetchLocale();
  
  runApp(MyApp(
    appLanguage: appLanguage,
  ));

}

class MyApp extends StatelessWidget {
  
  final AppLanguage appLanguage;

  MyApp({this.appLanguage});

  @override
  Widget build(BuildContext context) {

    return  MultiProvider(
          
                  providers: providers,

                  child: MaterialApp(
                            
                      localizationsDelegates: [
                         AppLocalizations.delegate,
                         GlobalMaterialLocalizations.delegate,
                         GlobalWidgetsLocalizations.delegate,
                      ],
          
                  initialRoute: RoutePaths.Login,
                  onGenerateRoute: Router.generateRoute,
                  )        
               );
        }  
}

表.dart

class Tables extends StatelessWidget {

  const Tables({Key key}) : super(key: key);

  @override
  Widget build(BuildContext context) {

    return BaseWidget<TablesModel>(
    
        model: TablesModel(api: Provider.of(context, listen: false)),
    
        onModelReady: (model) => model.fetchTables(),
    
        builder: (context, model, child) => model.busy

            ? Center(

                child: CircularProgressIndicator(),
              
              )
        
            : Expanded(
               
                 child: GridView.builder (
---

tables_model.dart

class TablesModel extends BaseModel {
  
  Api _api;

  TablesModel({@required Api api}) : _api = api;

  List<Tbl> tables;

  Future fetchTables() async {
    setBusy(true);
    tables = await _api.getTables();
    setBusy(false);
  }

  @override
  void dispose() {
    print('Tables has been disposed!!');
    super.dispose();
  }
}

api.dart

Future<List<Tbl>> getTables() async {
    
    var tables = List<Tbl>();

    try {

        var response = await http.get('$_baseUrl/tables/list');

        var parsed = json.decode(response.body) as List<dynamic>;
    
        if (parsed != null) {

           for (var table in parsed) {
    
               tables.add(Tbl.fromJson(table));
    
           }
        }

    } catch (e) {print(e); return null;}

    return tables;
  }

由于您的树中已经有一个MaterialApp并且已注册命名路由,因此这应该像添加一个调用以在您获得响应的同时推送您的登录页面一样简单。

首先,您应该修改getTables以使用Response object 的statusCode属性检查状态代码的response ,并显示以下代码块:

var response = await http.get('$_baseUrl/tables/list');

if(response.statusCode == 401) {
  //Act on status of 401 here
}

现在您有了一种检查响应何时具有状态码 401 的方法,您可以使用Navigator导航到您的登录页面。 Navigator需要BuildContext ,因此必须将其传递给getTables function。

这涉及将getTables修改为:

Future<List<Tbl>> getTables(BuildContext context) async {

并且fetchTables需要进行类似的更改:

Future fetchTables(BuildContext context) async {

然后,在调用这些方法的地方,将context向下传递:

Tables

model.fetchTables(context)

TablesModel

Future fetchTables(BuildContext context) async {
  setBusy(true);
  tables = await _api.getTables(context);
  setBusy(false);
}

最后在getTables中,您使用传递的context来使用Navigator

Future<List<Tbl>> getTables(BuildContext context) async {
  var tables = List<Tbl>();
  try {
      var response = await http.get('$_baseUrl/tables/list');

      //Check response status code
      if(response.statusCode == 401) {
        Navigator.of(context).pushNamed(RoutePaths.Login);//Navigator is used here to go to login only with 401 status code
        return null;
      }

      var parsed = json.decode(response.body) as List<dynamic>;

      if (parsed != null) {
         for (var table in parsed) {
             tables.add(Tbl.fromJson(table));
         }
      }

  } catch (e) {print(e); return null;}
  return tables;
}

而不是Navigator.of(context).pushNamed(RoutePaths.Login); ,您可以使用Navigator.pushNamed(context, RoutePaths.Login); 如果您愿意,但是正如您可以在此答案中看到的那样,它们在内部执行相同的操作。

现在,当状态码为 401 时,用户将被导航到登录屏幕。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM