Flutter功能未定义插件iampass的使用

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

Flutter功能未定义插件iampass的使用

iampass

IAMPASS Flutter插件 用于将应用程序连接到IAMPASS系统

有关系统的概述,请参阅入门指南。请注意,对于自定义iOS和Android应用的部分,其中包含有关配置您的应用程序权限和权限的信息。

该包可以用于:

  • 创建一个使用IAMPASS进行身份验证的应用程序。
  • 创建一个接收IAMPASS身份验证请求、收集身份验证数据并将其发送到IAMPASS的应用程序。 您的应用程序可以同时支持这两种功能,但如果您希望用户可以从不同的应用程序(例如Web应用程序)登录,则必须支持推送通知方法。 该包支持iOS和Android。

所有功能都由类Iampass提供。

import 'package:iampass/iampass.dart';
...
class _MyAppState extends State<MyApp> {
  final _iampassPlugin = Iampass();
  ...
}

开始使用

创建IAMPASS帐户

在您的应用程序可以使用IAMPASS之前,您必须创建一个IAMPASS帐户和应用程序。 请参阅入门指南

配置iOS应用程序

IAMPASS插件使用存储在iOS应用程序的info.plist文件中的自定义值。

<key>IAMPASS-AppID</key>
<string>您的IAMPASS应用程序ID</string>
<key>IAMPASS-AppSecret</key>
<string>您的IAMPASS应用程序密钥</string>

请参阅iOS指南

配置Android应用程序

请参阅Android指南以了解如何配置您的Android应用程序。

用户

IAMPASS要求您注册用户。您不应使用用户的用户名,而是应生成一个标识符传递给IAMPASS。 用户可以在移动应用程序或外部应用程序中注册。 如果用户是在外部应用程序中注册的,则必须在他们能够认证之前注册移动设备。


注册用户

在移动应用程序中注册用户

您可以使用iampass.addUser在移动应用程序中注册用户。这将注册IAMPASS用户、注册当前移动设备并执行必要的培训。 在下面的示例中,userID是应用程序为用户使用的标识符,notificationToken是从平台推送通知系统(APNS、FCM)获取的通知令牌。 如果您的应用程序不使用推送通知进行身份验证,则可以使用以*字符开头的任何字符串作为notificationToken。 创建的用户将存储在共享首选项中,以便在应用程序重新启动时检索。 此外,用户将存储在状态的_currentUser成员中,以便在后续调用中使用。

try {
  await _iampassPlugin.addUser(userID, notificationToken).then((user) {
    if (user != null) {
      // 用户已添加。
      // 将用户数据保存到共享首选项中,以便在应用程序重新启动时可以检索。
      String encoded = jsonEncode(user);
      encryptedSharedPreferences.setString("user", encoded);

      setState(() {
        _currentUser = user;
        _appUserID = userID;
      });
    }
  });
} on PlatformException catch (e) {
  // 插件未能完成请求。
  // 异常的code和message属性提供了失败原因的信息。
  ...
} catch (e) {
  // 发生了通用异常。
  ...
}
为现有用户注册设备

如果您已经通过IAMPASS注册了用户,但尚未注册其移动设备,可以使用iampass.registerUser。 在下面的示例中,userID是应用程序为用户使用的标识符,notificationToken是从平台推送通知系统(APNS、FCM)获取的通知令牌。 如果您的应用程序不使用推送通知进行身份验证,则可以使用以*字符开头的任何字符串作为notificationToken。 创建的用户将存储在共享首选项中,以便在应用程序重新启动时检索。 此外,用户将存储在状态的_currentUser成员中,以便在后续调用中使用。

try {
  await _iampassPlugin
      .registerDevice(userID, notificationToken)
      .then((device) {
    if (device != null) {
      // 保存用户数据。
      String encoded = jsonEncode(device);
      encryptedSharedPreferences.setString("user", encoded);
      setState(() {
        _currentUser = device;
      });
    }
  });
} on PlatformException catch (e) {
  // 插件未能完成请求。
  // 异常的code和message属性提供了失败原因的信息。
  ...
} catch (e) {
  // 发生了通用异常。
  ...
}

更新用户

当您的应用程序启动或推送通知令牌更改时,您应该使用存储的IAMPASSUser调用iampass.updateUser。 此方法的返回值是更新后的用户,并应替换存储的值。 下面的示例:

  • 调用了updateUser
  • 如果需要培训,则启动培训流程。
  • 如果不需要培训,则保存更新后的用户。
void onUpdateUser() async {
  try {
    await _iampassPlugin
        .updateUser(_appUserID, _currentUser!, "*notificationToken")
        .then((user) {
      // 用户已更新。
      if (user != null) {
        showSuccessMessage("updateUser Succeeded");
        if (user.trainingRequired) {
          // 执行培训
          doTraining(user);
        } else {
          String encoded = jsonEncode(user);
          encryptedSharedPreferences.setString("user", encoded);
          setState(() {
            _currentUser = user;
          });
          ...
        }
      }
    });
  } on PlatformException catch (e) {
    ...
  } catch (e) {
    ...
  }
}

void doTraining(IAMPASSUser user) async {
  try {
    await _iampassPlugin.trainUser(_currentUser!).then((user) {
      // 用户已更新。
      if (user != null) {
        String encoded = jsonEncode(user);
        encryptedSharedPreferences.setString("user", encoded);
        setState(() {
          _currentUser = user;
        });
        ...
      }
    });
  } on PlatformException catch (e) {
    ...
  } catch (e) {
    ...
  }
}

删除用户

要删除用户,请调用iampass.deleteUser

bool deleted = await _iampassPlugin.deleteUser(userID);

if (deleted) {
  ...
} else {
  ...
}
// 移除存储的用户数据。
encryptedSharedPreferences.remove("user");
setState(() {
  _currentUser = null;
});

身份验证

应用内身份验证

如果您的应用程序直接对用户进行身份验证,可以使用iampass.authenticateUser。此方法将显示身份验证UI并返回一个IAMPASSAuthenticationSession,可以用来控制用户的身份验证状态。 此方法只能用于由移动应用程序触发的身份验证事件。不会使用推送通知。 在下面的示例中,userID是用户的ID,currentUser是通过注册此移动设备获得的IAMPASSUser

void onAuthenticateUser() async {
  try {
    // 创建身份验证参数。
    // 在这种情况下,我们将使用默认的持续时间和身份验证方法。
    IAMPASSStartAuthenticationParams params =
        IAMPASSStartAuthenticationParams(
            userID, null, null, currentUser!);

    await _iampassPlugin.authenticateUser(params).then((session) {
      if (session == null) {
        // 身份验证失败。
      } else {
        // 身份验证完成。
        // 使用session.isAuthenticated检查结果
        ...
      }
    });
  } on PlatformException catch (e) {
    // 身份验证失败。
  } catch (e) {
    // 身份验证失败。
  }
}

您的应用程序应保存返回的IAMPASSAuthenticationSession,并在允许访问受保护资源之前使用它来检查用户的身份验证状态。 会话的状态是缓存的。应用程序应调用iampass.updateSession来更新缓存值。

try {
  await _iampassPlugin
      .updateSession(currentSession!)
      .then((updatedSession) {
    if (updatedSession != null) {
      setState(() {
        _currentSession = updatedSession;
      });

      // 会话已更新
      // 检查用户是否仍然被认证
      if (updatedSession.isAuthenticated) {
        // 用户已认证
      }
    }
  });
} on PlatformException catch (e) {
  // 更新失败。
} catch (e) {
  // 更新失败。
}
作为认证应用程序运行

如果您的应用程序旨在充当外部应用程序(如Web应用程序)的IAMPASS认证应用程序,您需要向您的应用程序添加推送通知处理功能。 您还必须在调用用户注册方法之前获取有效的通知令牌。 IAMPASS使用FCM进行Android推送通知,使用APNS或FCM进行iOS。 当您的应用程序收到推送通知时,它应该:

  • 检查通知是否来自IAMPASS
  • 使用通知有效负载构造IAMPASSAuthenticationRequest
  • 调用iampass.handleAuthenticationRequest
func application(
      _ application: UIApplication,
      didReceiveRemoteNotification userInfo: [AnyHashable: Any],
      fetchCompletionHandler completionHandler:
      @escaping (UIBackgroundFetchResult) -> Void
    ) {
        // 检查用户信息是否有action键
        if let action = data["action"] as? String{
        
            // 这是一个身份识别请求吗?
            if action == "identify"{
                // 这是一个IAMPASS身份验证请求
            }
      }
}

对于FCM消息,有效负载是:

"data" : {
    "action": "identify",
    ... IAMPASS数据。
}

如果action == "identify",则消息有效负载可以转换为JSON并使用IAMPASSAuthenticationRequest.fromJson转换为IAMPASSAuthenticationRequest。 您的应用程序应通过比较请求的userID属性与存储的IAMPASSUseruserID属性来检查推送通知是否针对此设备上的用户。如果匹配,则应用程序应将请求和用户传递给handleAuthenticationRequest


示例代码

以下是完整的示例代码:

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'dart:developer' as developer;

import 'package:flutter/services.dart';
import 'package:iampass/iampass.dart';
import 'package:fluttertoast/fluttertoast.dart';
import 'package:encrypted_shared_preferences/encrypted_shared_preferences.dart';
import 'package:iampass/iampass_user.dart';
import 'package:iampass/iampass_authentication_params.dart';
import 'package:iampass/iampass_authentication_session.dart';
import 'package:iampass/iampass_authentication_request.dart';
import 'package:iampass_example/splash_screen.dart';

class Init {
  static IAMPASSUser? currentUser;
  static String appUserID = "";
  static Future initialize() async {
    await _loadSettings();
    if (currentUser != null) {
      await _updateUser();
      await _saveUser();
    }
  }

  static _loadSettings() async {
    EncryptedSharedPreferences encryptedSharedPreferences =
        EncryptedSharedPreferences();

    String rawValue = await encryptedSharedPreferences.getString("user");

    if (rawValue.isNotEmpty) {
      // Convert to map
      Map<String, dynamic> m = jsonDecode(rawValue);
      currentUser = IAMPASSUser.fromJson(m);
    }

    appUserID = await encryptedSharedPreferences.getString("app-user-id");
  }

  static _updateUser() async {
    var iampassPlugin = Iampass();
    currentUser = await iampassPlugin.updateUser(
        "user", currentUser!, "notificationToken");
  }

  static _saveUser() async {
    if (currentUser != null) {
      String encoded = jsonEncode(currentUser);
      EncryptedSharedPreferences encryptedSharedPreferences =
          EncryptedSharedPreferences();

      if (!await encryptedSharedPreferences.setString("user", encoded)) {
        developer.log("Failed to save updated user.",
            name: "iampass.interface");
      }
    }
  }
}

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

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

  [@override](/user/override)
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final _iampassPlugin = Iampass();
  IAMPASSUser? _currentUser;
  IAMPASSAuthenticationSession? _currentSession;

  final TextEditingController usernameController = TextEditingController();
  EncryptedSharedPreferences encryptedSharedPreferences =
      EncryptedSharedPreferences();

  final Future _initFuture = Init.initialize();

  bool _hasInitialized = false;
  String _appUserID = "";

  [@override](/user/override)
  void initState() {
    super.initState();
    initPlatformState();
  }

  Future<IAMPASSUser?> loadIAMPassUser() async {
    String rawValue = await encryptedSharedPreferences.getString("user");

    if (rawValue.isNotEmpty) {
      // Convert to map
      Map<String, dynamic> m = jsonDecode(rawValue);
      IAMPASSUser u = IAMPASSUser.fromJson(m);
      developer.log("Added user", name: "iampass.interface");
      return u;
    }
    return null;
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    // If the widget was removed from the tree while the asynchronous platform
    // message was in flight, we want to discard the reply rather than calling
    // setState to update our non-existent appearance.
    if (!mounted) return;
  }

  void showErrorMessage(String message) {
    showMessage(message, true);
  }

  void showSuccessMessage(String message) {
    showMessage(message, false);
  }

  void showMessage(String message, bool error) {
    MaterialColor backgroundColor = error ? Colors.red : Colors.green;
    Fluttertoast.showToast(
        msg: message,
        toastLength: Toast.LENGTH_SHORT,
        gravity: ToastGravity.CENTER,
        timeInSecForIosWeb: 1,
        backgroundColor: backgroundColor,
        textColor: Colors.white,
        fontSize: 16.0);
  }

  void onAddUser() async {
    try {
      String userID = usernameController.text;
      await _iampassPlugin.addUser(userID, "*notificationToken").then((user) {
        if (user == null) {
          showErrorMessage("addUser Failed");
        } else {
          // The user has been added.
          String encoded = jsonEncode(user);

          encryptedSharedPreferences.setString("user", encoded);
          encryptedSharedPreferences.setString("app-user-id", userID);

          setState(() {
            _currentUser = user;
            _appUserID = userID;
          });
        }
      });
    } on PlatformException catch (e) {
      showErrorMessage(e.message ?? "addUser Failed.");
    } catch (e) {
      showErrorMessage("addUser Failed");
    }
  }

  void onRegisterUser() async {
    try {
      String userID = usernameController.text;
      await _iampassPlugin.registerUser(userID).then((registered) {
        if (!registered) {
          showErrorMessage("registerUser Failed");
        } else {
          showSuccessMessage("registerUser Succeeded");
        }
      });
    } on PlatformException catch (e) {
      showErrorMessage(e.message ?? "registerUser Failed");
    } catch (e) {
      showErrorMessage("registerUser Failed");
    }
  }

  void onRegisterDevice() async {
    try {
      String userID = usernameController.text;
      await _iampassPlugin
          .registerDevice(userID, "*notificationToken")
          .then((device) {
        if (device == null) {
          showErrorMessage("registerDevice Failed");
        } else {
          // Save the user
          String encoded = jsonEncode(device);

          encryptedSharedPreferences.setString("user", encoded);
          encryptedSharedPreferences.setString("app-user-id", userID);
          setState(() {
            _currentUser = device;
            _appUserID = userID;
          });
          showSuccessMessage("registerDevice Succeeded");
        }
      });
    } on PlatformException catch (e) {
      showErrorMessage(e.message ?? "registerDevice Failed");
    } catch (e) {
      showErrorMessage("registerDevice Failed");
    }
  }

  void onHandleRegistrationLink() async {
    try {
      String userID = usernameController.text;
      await _iampassPlugin
          .getRegistrationLink(userID, userID)
          .then((registrationLink) {
        if (registrationLink == null) {
          showErrorMessage("getRegistrationLink Failed");
        } else {
          // Save the user
          handleRegistrationLink(registrationLink);
          showSuccessMessage("registerDevice Succeeded");
        }
      });
    } on PlatformException catch (e) {
      showErrorMessage(e.message ?? "getRegistrationLink Failed");
    } catch (e) {
      showErrorMessage("getRegistrationLink Failed");
    }
  }

  void handleRegistrationLink(String registrationLink) async {
    String userID = usernameController.text;

    try {
      await _iampassPlugin
          .handleRegistrationLink(registrationLink, "*notificationToken")
          .then((device) {
        if (device == null) {
          showErrorMessage("handleRegistrationLink Failed");
        } else {
          // Save the user
          String encoded = jsonEncode(device);

          encryptedSharedPreferences.setString("user", encoded);
          encryptedSharedPreferences.setString("app-user-id", userID);
          setState(() {
            _currentUser = device;
            _appUserID = userID;
          });
          showSuccessMessage("registerDevice Succeeded");
        }
      });
    } on PlatformException catch (e) {
      showErrorMessage(e.message ?? "getRegistrationLink Failed");
    } catch (e) {
      showErrorMessage("getRegistrationLink Failed");
    }
  }

  void onAuthenticateUser() async {
    try {
      IAMPASSStartAuthenticationParams params =
          IAMPASSStartAuthenticationParams(
              _appUserID, null, null, _currentUser!);

      await _iampassPlugin.authenticateUser(params).then((session) {
        if (session == null) {
          showErrorMessage("authenticateUser Failed");
        } else {
          showSuccessMessage("authenticateUser Succeeded");
          setState(() {
            _currentSession = session;
          });
        }
      });
    } on PlatformException catch (e) {
      showErrorMessage(e.message ?? "Failed to authenticate user.");
    } catch (e) {
      showErrorMessage("Failed to authenticate user.");
    }
  }

  void onHandleAuthenticationRequest() async {
    try {
      IAMPASSStartAuthenticationParams params =
          IAMPASSStartAuthenticationParams(
              _appUserID, null, null, _currentUser!);

      await _iampassPlugin.debugStartAuth(params).then((result) async {
        if (result['session'] != null && result['request'] != null) {
          IAMPASSAuthenticationSession session = result['session'];
          IAMPASSAuthenticationRequest request = result['request'];

          await _iampassPlugin
              .handleAuthenticationRequest(request, _currentUser!)
              .then((session) {
            if (session) {
              showSuccessMessage("handleAuthenticationRequest Succeeded");
            } else {
              showErrorMessage("handleAuthenticationRequest Failed");
            }
          });
        }
      });
    } on PlatformException catch (e) {
      showErrorMessage(e.message ?? "handleAuthenticationRequest Failed");
    } catch (e) {
      showErrorMessage("handleAuthenticationRequest Failed");
    }
  }

  void onEndSession() async {
    try {
      await _iampassPlugin.endSession(_currentSession!).then((ended) {
        if (ended) {
          showSuccessMessage("endSession Succeeded");
          setState(() {
            _currentSession = null;
          });
        }
      });
    } catch (updateException) {
      showErrorMessage("endSession Failed");
    }
  }

  void onUpdateUser() async {
    try {
      await _iampassPlugin
          .updateUser(_appUserID, _currentUser!, "*notificationToken")
          .then((user) {
        // The user has been updated.
        if (user != null) {
          showSuccessMessage("updateUser Succeeded");
          if (user.trainingRequired) {
            // Do training
            doTraining(user);
          } else {
            setState(() {
              _currentUser = user;
            });
          }
        }
      });
    } on PlatformException catch (e) {
      showErrorMessage(e.message ?? "updateUser Failed");
    } catch (e) {
      showErrorMessage("updateUser Failed");
    }
  }

  void doTraining(IAMPASSUser user) async {
    try {
      await _iampassPlugin.trainUser(_currentUser!).then((user) {
        // The user has been updated.
        if (user != null) {
          setState(() {
            _currentUser = user;
          });
          showSuccessMessage("trainUser Succeeded");
        }
      });
    } on PlatformException catch (e) {
      showErrorMessage(e.message ?? "trainUser Failed");
    } catch (e) {
      showErrorMessage("trainUser Failed");
    }
  }

  void onUpdateSession() async {
    try {
      await _iampassPlugin
          .updateSession(_currentSession!)
          .then((updatedSession) {
        if (updatedSession != null) {
          setState(() {
            _currentSession = updatedSession;
          });

          showSuccessMessage("Updated Session");
        }
      });
    } catch (updateException) {
      showErrorMessage("Failed to update session.");
    }
  }

  void onDeleteCurrentUser() async {
    bool deleted = await _iampassPlugin.deleteUser(_appUserID);

    if (deleted) {
      showSuccessMessage("User removed");
    } else {
      showErrorMessage("Failed to remove user");
    }

    encryptedSharedPreferences.remove("user");
    setState(() {
      _currentUser = null;
      _appUserID = "";
    });
  }

  Widget homePage() {
    return Scaffold(
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: Column(
          children: <Widget>[
            Text('User: $_appUserID\n'),
            TextButton(
                onPressed: _currentUser == null ? null : onDeleteCurrentUser,
                child: const Text('Delete User')),
            TextButton(
                onPressed: _currentUser == null ? null : onUpdateUser,
                child: const Text('UpdateUser')),
            TextButton(
                onPressed: _currentUser != null && _currentSession == null
                    ? onAuthenticateUser
                    : null,
                child: const Text('authenticateUser')),
            TextButton(
                onPressed: _currentUser != null && _currentSession == null
                    ? onHandleAuthenticationRequest
                    : null,
                child: const Text('handleAuthenticationRequest')),
            TextButton(
                onPressed: _currentSession == null ? null : onEndSession,
                child: const Text('endSession')),
            TextButton(
                onPressed: _currentSession == null ? null : onUpdateSession,
                child: const Text('Update'))
          ],
        ));
  }

  Widget registerPage() {
    return Scaffold(
        appBar: AppBar(
          title: const Text('IAMPASS Example'),
        ),
        body: Column(
          children: <Widget>[
            FractionallySizedBox(
                widthFactor: 0.75,
                child: TextField(
                  obscureText: false,
                  controller: usernameController,
                  decoration: const InputDecoration(
                    border: OutlineInputBorder(),
                    labelText: 'Username',
                  ),
                )),
            TextButton(
                onPressed: _currentUser == null ? onAddUser : null,
                child: const Text('AddUser')),
            TextButton(
                onPressed: _currentUser == null ? onRegisterUser : null,
                child: const Text('RegisterUser')),
            TextButton(
                onPressed: _currentUser == null ? onRegisterDevice : null,
                child: const Text('RegisterDevice')),
            TextButton(
                onPressed:
                    _currentUser == null ? onHandleRegistrationLink : null,
                child: const Text('handleRegistrationLink'))
          ],
        ));
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
        home: FutureBuilder(
      future: _initFuture,
      builder: (context, snapshot) {
        if (!_hasInitialized) {
          _currentUser = Init.currentUser;
          _appUserID = Init.appUserID;
        }

        if (snapshot.connectionState == ConnectionState.done) {
          if (!_hasInitialized) {
            _currentUser = Init.currentUser;
            _appUserID = Init.appUserID;
            _hasInitialized = true;
          }
          if (_currentUser != null) {
            return homePage();
          } else {
            return registerPage();
          }
        } else {
          return const SplashScreen();
        }
      },
    ));
  }
}

更多关于Flutter功能未定义插件iampass的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter功能未定义插件iampass的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


在 Flutter 中,如果你遇到“功能未定义”或“插件未定义”的问题,通常是因为你尝试使用一个插件,但该插件并未正确安装或配置。以下是一些可能的解决方案,帮助你解决 iampass 插件的问题:

1. 确保插件已安装

首先,确保你已经将 iampass 插件添加到 pubspec.yaml 文件中:

dependencies:
  flutter:
    sdk: flutter
  iampass: ^1.0.0  # 请确保使用正确的版本号

然后运行 flutter pub get 来安装插件。

2. 检查插件是否正确导入

在你的 Dart 文件中,确保你已经正确导入了 iampass 插件:

import 'package:iampass/iampass.dart';

3. 检查插件的使用方式

查看 iampass 插件的文档,确保你正在正确使用它。例如,如果你需要调用某个方法,确保你已经按照文档中的说明进行操作。

// 示例代码
Iampass.doSomething();

4. 检查插件的兼容性

确保你使用的 iampass 插件版本与你的 Flutter SDK 版本兼容。你可以在 pub.dev 上查看插件的兼容性信息。

5. 清理和重建项目

有时候,清理和重建项目可以解决一些奇怪的问题。你可以尝试以下命令:

flutter clean
flutter pub get
flutter run

6. 检查插件的实现

如果你仍然遇到问题,可能需要检查 iampass 插件的实现,或者查看是否有其他开发者遇到了类似的问题。你可以在 pub.dev 或 GitHub 上查看插件的 Issue 页面。

7. 检查 Flutter 版本

确保你的 Flutter SDK 是最新版本。你可以通过以下命令更新 Flutter:

flutter upgrade

8. 检查平台配置

某些插件可能需要特定的平台配置(如 Android 或 iOS)。确保你已经按照插件的文档进行了正确的平台配置。

9. 重新安装插件

如果以上方法都不奏效,尝试删除 iampass 插件并重新安装:

flutter pub remove iampass
flutter pub add iampass
回到顶部
AI 助手
你好,我是IT营的 AI 助手
您可以尝试点击下方的快捷入口开启体验!