You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flutter应用集成Google密码管理器实现多账号凭据管理及生物识别启用指南

Flutter应用集成Google密码管理器实现多账号凭据管理及生物识别启用指南

嘿,我来帮你一步步实现这个需求,刚好之前做过类似的功能,咱们从基础配置到具体功能挨个梳理:

一、先搞定项目的自动填充基础配置

要让Google密码管理器能识别你的登录表单,得先给项目做些配置:

  • Android端:在android/app/src/main/AndroidManifest.xml里,给登录页面的Activity加上自动填充相关属性,同时确保有网络权限(毕竟要和Google服务交互):
    <uses-permission android:name="android.permission.INTERNET" />
    
    <activity
        android:name=".MainActivity"
        ...
        android:autofillHints="username,password">
    </activity>
    
  • iOS端:在ios/Runner/Info.plist里添加自动填充的权限描述,不然会被系统拒:
    <key>NSAutoFillUsageDescription</key>
    <string>需要使用自动填充功能来保存和填充您的账号密码</string>
    

二、用安全存储管理多账号凭据

我推荐用flutter_secure_storage包来存储账号密码,它会自动用系统级的加密方式保存,比SharedPreferences安全多了:

  1. 先在pubspec.yaml里引入依赖:
    dependencies:
      flutter_secure_storage: ^9.0.0 # 用最新版本就行
    
  2. 初始化存储实例,建议放在全局或者登录页面的State里:
    final _storage = FlutterSecureStorage();
    
  3. 设计存储结构:我习惯用一个key存所有账号的列表,每个账号的密码单独存,比如:
    • 账号列表存在user_accounts这个key下,值是JSON格式的字符串(比如["user1@gmail.com", "user2@outlook.com"]
    • 每个账号的密码存在password_${userId}这个key下,比如password_user1@gmail.com

三、实现账号选择弹窗+自动填充

接下来就是点击用户名输入框弹出账号选择列表,选完自动填密码的逻辑:

  1. 先读取保存的账号列表:
    Future<List<String>> _getSavedAccounts() async {
      final accountsStr = await _storage.read(key: 'user_accounts');
      if (accountsStr == null) return [];
      return List<String>.from(jsonDecode(accountsStr));
    }
    
  2. 在用户名输入框的onTap事件里触发弹窗:
    TextFormField(
      controller: _usernameController,
      autofillHints: const [AutofillHints.username],
      onTap: () async {
        final accounts = await _getSavedAccounts();
        if (accounts.isEmpty) return;
        // 弹出底部弹窗或者AlertDialog选择账号
        final selectedAccount = await showModalBottomSheet<String>(
          context: context,
          builder: (context) => ListView.builder(
            itemCount: accounts.length,
            itemBuilder: (context, index) => ListTile(
              title: Text(accounts[index]),
              onTap: () => Navigator.pop(context, accounts[index]),
            ),
          ),
        );
        if (selectedAccount != null) {
          _usernameController.text = selectedAccount;
          // 自动填充对应的密码
          final password = await _storage.read(key: 'password_$selectedAccount');
          _passwordController.text = password ?? '';
        }
      },
      decoration: const InputDecoration(labelText: '用户名'),
    )
    

四、新增/修改账号的保存逻辑

当用户输入新账号或者修改密码后,要把凭据保存起来:

Future<void> _saveCredentials(String userId, String password) async {
  final accounts = await _getSavedAccounts();
  // 如果账号已存在,就更新密码;不存在就添加到列表
  if (!accounts.contains(userId)) {
    accounts.add(userId);
    await _storage.write(key: 'user_accounts', value: jsonEncode(accounts));
  }
  // 保存密码
  await _storage.write(key: 'password_$userId', value: password);
}

你可以把这个方法绑定到登录按钮的点击事件里,比如用户登录成功后调用它,或者加个“保存凭据”的开关让用户选择。

五、启用生物识别验证

要加生物识别的话,用local_auth包就很方便:

  1. 先引入依赖:
    dependencies:
      local_auth: ^2.1.7 # 最新版本
    
  2. 先检查设备是否支持生物识别:
    Future<bool> _isBiometricAvailable() async {
      final auth = LocalAuthentication();
      return await auth.canCheckBiometrics || await auth.isDeviceSupported();
    }
    
  3. 在需要验证的地方(比如登录前、查看密码前)调用验证:
    Future<bool> _authenticateWithBiometrics() async {
      final auth = LocalAuthentication();
      try {
        return await auth.authenticate(
          localizedReason: '请验证您的身份以继续',
          options: const AuthenticationOptions(
            biometricOnly: true, // 只允许生物识别验证
            stickyAuth: true,
          ),
        );
      } catch (e) {
        print(e);
        return false;
      }
    }
    
    比如你可以在用户选择账号后,先调用生物识别验证,通过了再填充密码,这样更安全。

一些小提示

  • 记得在用户退出登录或者切换账号时,清空输入框的内容,避免信息残留
  • 对于Google密码管理器的系统级自动填充,确保你的输入框设置了正确的autofillHints,系统会自动识别并弹出保存/填充提示
  • 测试的时候要确保设备已经登录了Google账号,并且开启了密码管理器功能

备注:内容来源于stack exchange,提问作者Tanmoy

火山引擎 最新活动