首页 > 解决方案 > Flutter:local_auth 可以通过按返回键绕过

问题描述

我正在使用local_auth进行用户验证。

我的应用程序的根小部件是一个stateless小部件。

错误:身份验证屏幕照常弹出。如果指纹(或密码)匹配,则用户可以访问该应用程序。但是,如果按下后退按钮(身份验证屏幕仍处于打开状态),身份验证窗口将消失,用户无需身份验证即可访问应用程序。

我正在使用Flutter-2.5.3local_auth-1.1.8

这是main.dart

//other imports here
import 'package:local_auth/local_auth.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  var localAuth = LocalAuthentication();
  SharedPreferences prefs = await SharedPreferences.getInstance();

  if (prefs.getBool('auth') == true) {
    await localAuth.authenticate(
        localizedReason: 'Authenticate to access Notes',
        useErrorDialogs: true,
        stickyAuth: true,);
  }

  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then((_) {
    runApp(ProviderScope(child: MyApp()));
  });
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    //returns my widget
  }
}

我尝试runApp在条件下移动块,以便仅在身份验证成功时才调用主根窗口。然而结果还是一样。这就是我所做的:

if (prefs.getBool('auth') == true) {
    var authenticate = await localAuth.authenticate(
        localizedReason: 'Authenticate to access Notes',
        useErrorDialogs: true,
        stickyAuth: true,);
    if (authenticate == true) {
      await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then((_) {
        runApp(ProviderScope(child: MyApp()));
      });
    }
}

标签: androidflutterdartflutter-dependencies

解决方案


这对我有用:

  1. 更改MyAppStatefulWidget.

  2. 添加一个等待的函数,在用户可以访问小部件之前尝试对用户进行身份验证(即构建函数)。

修改代码:

//other imports here
import 'package:local_auth/local_auth.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();

  //removing the authentication block from the main method
  await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp, DeviceOrientation.portraitDown]).then((_) {
    runApp(ProviderScope(child: MyApp()));
  });
}

class MyApp extends StatefulWidget {  //changing MyApp to StatefulWidget
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();
    _authenticate();  //the function that handles authentication
  }

  void _authenticate() async {
    var localAuth = LocalAuthentication();

    SharedPreferences prefs = await SharedPreferences.getInstance();

    if (prefs.getBool('auth') == true) {
      var authenticate = await localAuth.authenticate(
        localizedReason: 'Authenticate to access Notes',
        useErrorDialogs: true,
        //Not using stickyAuth because:  https://github.com/flutter/flutter/issues/83773
        // stickyAuth: true,
      );
      if (authenticate != true) 
        exit(0);  //exiting the app if the authentication failed
    }
  }

  @override
  Widget build(BuildContext context) {
    //returns my widget
  }
}

推荐阅读