Flutter高级平台认证UI插件senior_platform_authentication_ui的使用

发布于 1周前 作者 eggper 来自 Flutter

Flutter高级平台认证UI插件senior_platform_authentication_ui的使用

Senior Platform Authentication Ui

这个项目的目的是为与Senior X集成的应用程序提供独特的认证体验。该包使用了已经实现到Senior X后端认证的senior_platform_authentication dart包。

因此,为了保持认证体验的完整性,需要进行Senior-X平台认证的应用程序应该依赖于这个包。如果需要对认证流程进行一些适应或更大程度的自定义,可以使用senior_platform_authentication包并手动实现规则,或者贡献此包以添加必要的用例。

架构

架构基于Clean Architecture,但在项目的技术分析后进行了针对项目的某些调整。

[Diagrama da arquitetura definida] (此处应有架构图)

如何使用

  1. pubspec.yaml中添加包并执行flutter pub get
dependencies:
  senior_platform_authentication_ui: ^1.0.1

注意:请检查最新版本

  1. 导入包senior_platform_authentication_ui
import 'package:senior_platform_authentication_ui/senior_platform_authentication_ui.dart';
  1. 必须在应用程序的主线程中初始化主类。
SeniorAuthentication.initialize(
  encryptionKey: 'sua chave de criptografia de 32 caracteres alfanuméricos', // 32字符的加密密钥
);

也可以选择初始化环境:

SeniorAuthentication.initialize(
  encryptionKey: 'sua chave de criptografia de 32 caracteres alfanuméricos',
  platformEnvironment: PlatformEnvironment.homolog, // 环境设置为homolog
);

此外,initialize方法还有其他配置选项,请参见下表:

参数 默认值 描述
platformEnvironment PlatformEnvironment.production 请求将被定向到的环境。
enableLoginOffline false 启用或禁用离线登录。
automaticLogon true 定义是否自动登录。
includePhoto false 启用或禁用获取用户信息时包含照片。
baseUrl ‘’ platformEnvironment值为PlatformEnvironment.custom时,定义自定义baseUrl。
frontendUrl ‘’ platformEnvironment值为PlatformEnvironment.custom时,定义自定义frontendUrl。
enableBiometry false 启用生物识别登录选项。
enableBiometryOnly false 如果希望用户仅使用生物识别登录,需启用此选项,并且enableBiometry必须为true。
enableLoginWithKey false 当希望通过设备上的应用密钥进行身份验证时启用。
encryptionKey N/A 包含32个字母数字字符的加密密钥,用于存储和读取敏感数据。

注意: encryptionKey参数应始终相同,否则无法解密数据。

  1. 将一个BlocProvider放在Flutter应用程序的根目录中。这样可以在应用程序生命周期中的任何时刻访问认证状态。

注意: 强烈建议将Senior Design System组件放在第一级,然后在其下方放置BlocProvider。senior_platform_authentication_ui包是基于Senior的设计系统构建的。

class ExampleApp extends StatelessWidget {
  const ExampleApp({super.key});

  [@override](/user/override)
  Widget build(BuildContext context) {
    return SeniorDesignSystem(
      child: BlocProvider(
        create: (context) => AuthenticationBloc()..add(CheckAuthenticationRequested()),
        child: const AppView(),
      ),
    );
  }
}

重要的是要注意,AuthenticationBloc作为一个单例工作。

推荐使用以下方法根据认证状态控制路由:

class AppView extends StatefulWidget {
  const AppView({super.key});

  [@override](/user/override)
  State<AppView> createState() => _AppViewState();
}

class _AppViewState extends State<AppView> {
  final _navigatorKey = GlobalKey<NavigatorState>();

  NavigatorState get _navigator => _navigatorKey.currentState!;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: _navigatorKey,
      builder: (context, child) {
        return BlocListener<AuthenticationBloc, AuthenticationState>(
          listener: (context, state) {
            switch (state.status) {
              case AuthenticationStatus.authenticated:
                _navigator.pushAndRemoveUntil<void>(
                  MaterialPageRoute<void>(builder: (_) => const HomeScreen()),
                  (route) => false,
                );
                break;
              case AuthenticationStatus.unauthenticated:
                _navigator.pushAndRemoveUntil<void>(
                  MaterialPageRoute<void>(
                    builder: (_) => const LoginScreen(),
                  ),
                  (route) => false,
                );
                break;
              case AuthenticationStatus.unknown:
                break;
            }
          },
          child: child,
        );
      },
      onGenerateRoute: (_) => SplashScreen.route(),
    );
  }
}

生物识别

senior_platform_authentication_ui包提供了与local_auth包的集成,以便使用生物识别。

要在项目中启用生物识别,请按照以下步骤操作:

Android配置

在文件android/app/src/main/AndroidManifest.xml中,在<application>标签内添加以下代码行:

<uses-permission android:name="android.permission.USE_BIOMETRIC" />
iOS配置
  • ios/Runner/Info.plist
    • 在标签内添加以下代码行:
    • 此代码行启用FaceId的使用。
  <key>NSFaceIDUsageDescription</key>
  <string>authenticating using face id</string>
MainActivity配置

需要更改MainActivity.java或MainActivity.kt文件。示例中更改了MainActivity.kt文件。由于包需要验证注册的生物识别信息,因此需要添加以下代码行:

package com.example.senior_authentication_ui_example

import io.flutter.embedding.android.FlutterFragmentActivity

class MainActivity: FlutterFragmentActivity() {

}

若产品在访问生物识别时遇到问题,建议检查local_auth包以确认是否有任何更新或必要的配置以访问生物识别。

要使用生物识别功能,应在项目中实现包的main.dart文件中添加以下代码行:

SeniorAuthentication.initialize(
  enableBiometry: true, // 启用生物识别登录选项。
  enableBiometryOnly: true, // 当产品只允许生物识别登录时启用此选项,排除密码或PIN等其他安全形式。
);

示例Demo

以下是完整的示例demo代码:

import 'dart:ui';

import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:senior_design_system/senior_design_system.dart';
import 'package:senior_platform_authentication_ui/senior_platform_authentication_ui.dart';

void main() {
  SeniorAuthentication.initialize(
    automaticLogon: true, // 自动登录
    enableLoginOffline: true, // 启用离线登录
    restUrl: 'https://cloud-leaf.senior.com.br/t/senior.com.br/bridge/1.0/rest', // REST URL
    platformEnvironment: PlatformEnvironment.cloudLeaf, // 环境设置为cloudLeaf
    enableBiometry: true, // 启用生物识别
    enableBiometryOnly: false, // 不仅限于生物识别
    encryptionKey: 'SuaChaveDeEncriptarCom32Caracter', // 加密密钥
  );

  runApp(const ExampleApp());
}

class ExampleApp extends StatefulWidget {
  const ExampleApp({super.key});

  [@override](/user/override)
  State<ExampleApp> createState() => _ExampleAppState();
}

class _ExampleAppState extends State<ExampleApp> {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return SeniorDesignSystem(
      child: BlocProvider(
        create: (context) => AuthenticationBloc()
          ..add(CheckAuthenticationRequested(username: '')), // 检查认证请求
        child: const AppView(),
      ),
    );
  }
}

class AppView extends StatefulWidget {
  const AppView({super.key});

  [@override](/user/override)
  State<AppView> createState() => _AppViewState();
}

class _AppViewState extends State<AppView> with WidgetsBindingObserver {
  final _navigatorKey = GlobalKey<NavigatorState>();
  bool isBiometricRequested = false;
  bool isHidden = false;
  DateTime? backgroundTime;

  [@override](/user/override)
  void initState() {
    WidgetsBinding.instance.addObserver(this);
    super.initState();
  }

  [@override](/user/override)
  void dispose() {
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  [@override](/user/override)
  void didChangeAppLifecycleState(AppLifecycleState state) async {
    if (isHidden && state == AppLifecycleState.resumed) {
      final authenticationBloc = context.read<AuthenticationBloc>();
      if (authenticationBloc.state.status == AuthenticationStatus.authenticated) {
        if (backgroundTime != null) {
          final currentTime = DateTime.now();
          final elapsedDuration = currentTime.difference(backgroundTime!);

          if (elapsedDuration.inMinutes > 3) {
            authenticationBloc.add(CheckAuthenticationRequested(username: authenticationBloc.state.username));
          }
        }
      }
      isHidden = false;
    }

    if (!isHidden) {
      isHidden = state == AppLifecycleState.hidden;
      if (isHidden) {
        backgroundTime = DateTime.now();
      }
    }
  }

  NavigatorState get _navigator => _navigatorKey.currentState!;

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey: _navigatorKey,
      debugShowCheckedModeBanner: false,
      builder: (context, child) {
        return BlocListener<AuthenticationBloc, AuthenticationState>(
          listener: (context, state) {
            switch (state.status) {
              case AuthenticationStatus.authenticated:
                _navigator.pushAndRemoveUntil<void>(
                  MaterialPageRoute<void>(builder: (_) => const HomeScreen()),
                  (route) => false,
                );
                break;
              case AuthenticationStatus.unauthenticated:
                _navigator.pushAndRemoveUntil<void>(
                  MaterialPageRoute<void>(builder: (_) => const LoginScreen()),
                  (route) => false,
                );
                break;
              case AuthenticationStatus.unknown:
                break;
              case AuthenticationStatus.offline:
                _navigator.pushAndRemoveUntil<void>(
                  MaterialPageRoute<void>(builder: (_) => const HomeScreen()),
                  (route) => false,
                );
                break;
            }
          },
          child: child,
        );
      },
      onGenerateRoute: (_) => SplashScreen.route(),
    );
  }

  Widget blockWidget() {
    return BackdropFilter(
      filter: ImageFilter.blur(sigmaX: 15.0, sigmaY: 15.0),
      child: Container(
        decoration: BoxDecoration(
          color: Colors.deepPurpleAccent.shade200.withOpacity(.5),
        ),
      ),
    );
  }
}

更多关于Flutter高级平台认证UI插件senior_platform_authentication_ui的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter高级平台认证UI插件senior_platform_authentication_ui的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter项目中集成并使用senior_platform_authentication_ui插件的示例代码。这个插件假设是用于高级平台认证UI的,但请注意,具体的插件实现细节和API可能因插件版本而异,因此以下代码只是一个示例,你可能需要根据实际插件文档进行调整。

首先,确保你已经在pubspec.yaml文件中添加了senior_platform_authentication_ui依赖:

dependencies:
  flutter:
    sdk: flutter
  senior_platform_authentication_ui: ^最新版本号  # 替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来,在你的Flutter应用中,你可以按照以下方式使用senior_platform_authentication_ui插件。以下是一个简单的示例,展示如何在按钮点击时触发认证UI:

import 'package:flutter/material.dart';
import 'package:senior_platform_authentication_ui/senior_platform_authentication_ui.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Senior Platform Authentication UI Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {

  void _triggerAuthentication() async {
    try {
      // 调用插件提供的认证方法
      // 注意:这里的`authenticate`方法和参数是假设的,实际使用时请参考插件文档
      bool result = await SeniorPlatformAuthenticationUi.authenticate(
        context: context,
        // 可能需要的其他参数,如平台类型、认证配置等
        platform: 'android', // 示例平台类型
        config: {
          // 示例配置,实际使用时请参考插件文档
          'apiKey': 'your_api_key',
          'redirectUri': 'your_redirect_uri',
        },
      );

      if (result) {
        // 认证成功后的处理
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('认证成功!')),
        );
      } else {
        // 认证失败后的处理
        ScaffoldMessenger.of(context).showSnackBar(
          SnackBar(content: Text('认证失败,请重试.')),
        );
      }
    } catch (e) {
      // 处理异常
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text('发生错误: $e')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Senior Platform Authentication UI Demo'),
      ),
      body: Center(
        child: ElevatedButton(
          onPressed: _triggerAuthentication,
          child: Text('触发认证'),
        ),
      ),
    );
  }
}

请注意:

  1. 插件API:上述代码中的SeniorPlatformAuthenticationUi.authenticate方法和参数是假设的。你需要查阅senior_platform_authentication_ui插件的实际文档,了解如何正确调用认证方法和传递参数。

  2. 错误处理:示例代码中包含了基本的错误处理,但在实际项目中,你可能需要更详细的错误处理和用户反馈机制。

  3. UI设计:上述示例使用了Flutter的Material设计,你可以根据需要自定义UI设计。

  4. 依赖版本:确保你使用的插件版本与Flutter SDK兼容,并查看插件的更新日志和发行说明,以获取最新的功能和修复。

由于senior_platform_authentication_ui是一个假设的插件名称,因此实际使用时,请替换为真实存在的插件名称和API。

回到顶部