Flutter功能未定义插件iampass的使用
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
属性与存储的IAMPASSUser
的userID
属性来检查推送通知是否针对此设备上的用户。如果匹配,则应用程序应将请求和用户传递给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
更多关于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