Flutter前端管理与安全插件frontegg_flutter的使用
Flutter前端管理与安全插件frontegg_flutter的使用
Frontegg 是一个全栈用户管理平台,为软件团队提供了产品时代所需的基础功能。
目录
项目需求
- 最低iOS部署版本 => 14
- 最低Android SDK版本 => 26
开始使用
准备Frontegg工作区
导航至 Frontegg Portal Settings,如果还没有应用程序,请按照集成步骤操作。 从 Frontegg Portal Domain 复制Frontegg域名。
- 导航至 登录方法设置
- 为iOS切换托管登录方式:
- 添加
{{IOS_BUNDLE_IDENTIFIER}}://{{FRONTEGG_BASE_URL}}/ios/oauth/callback
- 添加
- 为Android切换托管登录方式:
- 添加
{{ANDROID_PACKAGE_NAME}}://{{FRONTEGG_BASE_URL}}/android/oauth/callback
- 添加
https://{{FRONTEGG_BASE_URL}}/oauth/account/redirect/android/{{ANDROID_PACKAGE_NAME}}
- 添加
- 添加
{{FRONTEGG_BASE_URL}}/oauth/authorize
- 将
IOS_BUNDLE_IDENTIFIER
替换为您的应用程序标识符 - 将
FRONTEGG_BASE_URL
替换为您frontegg的基本URL - 将
ANDROID_PACKAGE_NAME
替换为您的Android包名
将frontegg包添加到项目中
使用包管理器 pub
安装frontegg Flutter库。
终端:
dart pub add frontegg_flutter
或手动:
dependencies:
frontegg_flutter: ^1.0.0
设置iOS项目
创建Frontegg plist文件
为了使您的SwiftUI应用程序能够与Frontegg通信,您需要在iOS项目目录下(例如ios/Runner)创建一个名为 Frontegg.plist
的新文件,并将其包含在XCode项目中。此文件将存储Frontegg SDK使用的变量值:
如何创建:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>baseUrl</key>
<string>https://[DOMAIN_HOST_FROM_PREVIOUS_STEP]</string>
<key>clientId</key>
<string>[CLIENT_ID_FROM_PREVIOUS_STEP]</string>
</dict>
</plist>
处理通过URL打开应用
对于Objective-C:
- 在项目中创建
FronteggSwiftAdapter.swift
并添加以下代码:
// FronteggSwiftAdapter.swift
import Foundation
import FronteggSwift
@objc(FronteggSwiftAdapter)
public class FronteggSwiftAdapter: NSObject {
@objc public static let shared = FronteggSwiftAdapter()
@objc public func handleOpenUrl(_ url: URL) -> Bool {
return FronteggAuth.shared.handleOpenUrl(url)
}
}
- 打开
AppDelegate.m
文件并导入Swift头文件:
#import "<YOUR_PROJECT_NAME>-Swift.h"
- 向
AppDelegate.m
添加URL处理器:
#import "<YOUR_PROJECT_NAME>-Swift.h"
// ...CODE...
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url
options:(NSDictionary<UIApplicationOpenURLOptionsKey, id> *)options
{
if([[FronteggSwiftAdapter shared] handleOpenUrl:url] ){
return TRUE;
}
return [RCTLinkingManager application:app openURL:url options:options];
}
- (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity
restorationHandler:(nonnull void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler
{
if (userActivity.webpageURL != NULL){
if([[FronteggSwiftAdapter shared] handleOpenUrl:userActivity.webpageURL] ){
return TRUE;
}
}
return [RCTLinkingManager application:application
continueUserActivity:userActivity
restorationHandler:restorationHandler];
}
对于Swift:
- 向
AppDelegate.swift
添加URL处理器:
import UIKit
import Flutter
import FronteggSwift
@main
@objc class AppDelegate: FlutterAppDelegate {
/*
* 当应用程序使用URL启动时调用。您可以在此处添加额外的处理逻辑,
* 但如果您希望App API支持跟踪应用URL打开,请保留此调用。
*/
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
if(FronteggAuth.shared.handleOpenUrl(url, true)){
return true
}
return ApplicationDelegateProxy.shared.application(app, open: url, options: options)
}
/*
* 当应用程序使用活动(包括通用链接)启动时调用。
* 您可以在此处添加额外的处理逻辑,但如果您希望App API支持
* 跟踪应用URL打开,请保留此调用。
*/
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
if let url = userActivity.webpageURL {
if(FronteggAuth.shared.handleOpenUrl(url, true)){
return true
}
}
return ApplicationDelegateProxy.shared.application(application, continue: userActivity, restorationHandler: restorationHandler)
}
}
配置iOS关联域
配置您的iOS关联域是为了实现魔法链接认证、重置密码、激活账户等功能。
为了向您的Frontegg应用添加iOS关联域,您需要更新每个集成的Frontegg环境中您想要使用的iOS关联域。发送POST请求到 https://api.frontegg.com/vendors/resources/associated-domains/v1/ios
并附带以下有效负载:
{
“appId”:[YOUR_ASSOCIATED_DOMAIN]
}
接下来,您需要向您的iOS应用程序添加关联域。要执行此操作,请遵循以下步骤:
- 在Xcode中打开您的项目。
- 在项目导航器中选择您的项目。
- 选择您的目标。
- 选择“签名和能力”选项卡。
- 展开“关联域”部分。
- 点击+按钮。
- 输入您的关联域,格式为
applinks:[YOUR_ASSOCIATED_DOMAIN]
。 - 输入您的关联域,格式为
webcredentials:[YOUR_ASSOCIATED_DOMAIN]
。 - 点击完成。
多应用iOS支持
本指南概述了配置iOS应用以支持多个应用的步骤。
步骤1:修改Frontegg.plist文件
向Frontegg.plist文件中添加 applicationId
:
<plist version="1.0">
<dict>
<key>applicationId</key>
<string>your-application-id-uuid</string>
<key>baseUrl</key>
<string>https://your-domain.fronteg.com</string>
<key>clientId</key>
<string>your-client-id-uuid</string>
</dict>
</plist>
卸载应用后注销用户
如果您希望用户在重新安装应用后不保持登录状态,请向 Frontegg.plist
文件中添加 keepUserLoggedInAfterReinstall
属性:
<plist version="1.0">
<dict>
<key>keepUserLoggedInAfterReinstall</key>
<false/>
...
</dict>
</plist>
默认情况下,keepUserLoggedInAfterReinstall
为 true
。
设置Android项目
设置最低SDK版本
为了设置您的Android最低SDK版本,请打开根级gradle文件 android/build.gradle
,并在 buildscript.ext
下添加或编辑 minSdkVersion
:
buildscript {
ext {
minSdkVersion = 26
// ...
}
}
配置构建配置字段
为了使您的Android应用能够与Frontegg通信,您需要在gradle android/app/build.gradle
中添加 buildConfigField
属性。此属性将存储frontegg主机名(不包括协议https)和来自上一步的客户端ID:
def fronteggDomain = "FRONTEGG_DOMAIN_HOST.com" // 不包括协议 https://
def fronteggClientId = "FRONTEGG_CLIENT_ID"
android {
defaultConfig {
manifestPlaceholders = [
"package_name" : applicationId,
"frontegg_domain" : fronteggDomain,
"frontegg_client_id": fronteggClientId
]
buildConfigField "String", 'FRONTEGG_DOMAIN', "\"$fronteggDomain\""
buildConfigField "String", 'FRONTEGG_CLIENT_ID', "\"$fronteggClientId\""
buildConfigField "Boolean", 'FRONTEGG_USE_ASSETS_LINKS', "true" /** For using frontegg domain for deeplinks **/
buildConfigField "Boolean", 'FRONTEGG_USE_CHROME_CUSTOM_TABS', "true" /** For using custom chrome tab for social-logins **/
}
}
注意:
FRONTEGG_USE_ASSETS_LINKS
默认为 true
。
FRONTEGG_USE_CHROME_CUSTOM_TABS
默认为 true
。
因此,如果您未设置这些值,我们将使用默认值。
如果 android
部分内没有 buildConfig=true
,请在 android/app/build.gradle
中添加它:
android {
buildFeatures {
buildConfig = true
}
}
配置Android AssetLinks
配置您的Android AssetLinks
是为了实现魔法链接认证、重置密码、激活账户/使用身份提供商登录。
要将您的 AssetLinks
添加到您的Frontegg应用,您需要更新每个集成的Frontegg环境中您想要使用的 AssetLinks
。发送POST请求到 https://api.frontegg.com/vendors/resources/associated-domains/v1/android
并附带以下有效负载:
{
"packageName": "YOUR_APPLICATION_PACKAGE_NAME",
"sha256CertFingerprints": ["YOUR_KEYSTORE_CERT_FINGERPRINTS"]
}
每个Android应用有多个证书指纹,要获取您的 DEBUG
sha256CertFingerprint,您需要运行以下命令:
对于调试模式,运行以下命令并复制 SHA-256
值:
注意:确保选择的变体和配置等于 debug
./gradlew signingReport
对于发布模式,使用keytool从您的 Release
keystore文件中提取SHA256:
keytool -list -v -keystore /PATH/file.jks -alias YourAlias -storepass *** -keypass ***
启用Chrome自定义标签页进行社交登录
要在Android应用中启用使用Chrome自定义标签页进行社交登录,您需要修改 android/app/build.gradle
文件。添加一个布尔类型的 buildConfigField
用于 FRONTEGG_USE_CHROME_CUSTOM_TABS
标志并将其设置为true。
默认情况下,SDK默认使用Chrome浏览器进行社交登录。
def fronteggDomain = "FRONTEGG_DOMAIN_HOST.com" // 不包括协议 https://
def fronteggClientId = "FRONTEGG_CLIENT_ID"
android {
defaultConfig {
manifestPlaceholders = [
"package_name" : applicationId,
"frontegg_domain" : fronteggDomain,
"frontegg_client_id": fronteggClientId
]
buildConfigField "String", 'FRONTEGG_DOMAIN', "\"$fronteggDomain\""
buildConfigField "String", 'FRONTEGG_CLIENT_ID', "\"$fronteggClientId\""
buildConfigField "Boolean", 'FRONTEGG_USE_CHROME_CUSTOM_TABS', "true"
}
}
多应用Android支持
本指南概述了配置Android应用以支持多个应用的步骤。
步骤1:修改Build.gradle文件
在 build.gradle
文件中添加 FRONTEGG_APPLICATION_ID
构建配置字段:
def fronteggApplicationId = "your-application-id-uuid"
...
android {
...
buildConfigField "String", 'FRONTEGG_APPLICATION_ID', "\"$fronteggApplicationId\""
}
用法
将根Widget包装在FronteggProvider中
import 'package:flutter/material.dart';
import 'package:frontegg_flutter/frontegg_flutter.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: FronteggProvider(
child: const MainPage(),
),
);
}
}
或者使用 provider
插件或其他合适的插件包装,不要忘记 dispose
FronteggFlutter
:
import 'package:flutter/material.dart';
import 'package:frontegg_flutter/frontegg_flutter.dart';
import 'package:provider/provider.dart';
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Provider(
create: (_) => FronteggFlutter(),
dispose: (_, frontegg) => frontegg.dispose(),
child: const MainPage(),
),
);
}
}
访问Frontegg实例
要获取 FronteggFlutter
实例,请使用 Frontegg
BuildContext扩展:
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
final frontegg = context.frontegg;
return const SizedBox();
}
}
使用frontegg登录
要使用frontegg登录,可以使用 context.frontegg
访问器并调用 login
方法:
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
final frontegg = context.frontegg;
return Scaffold(
body: Center(
child: ElevatedButton(
child: const Text("Login"),
onPressed: () async {
await frontegg.login();
},
),
),
);
}
}
切换frontegg租户
要使用frontegg切换租户,可以使用 context.frontegg
访问器并调用 switchTenant
方法:
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
final frontegg = context.frontegg;
return Scaffold(
body: Center(
child: ElevatedButton(
child: const Text("Switch Tenant"),
onPressed: () async {
final tenantId = "TENANT_ID";
await frontegg.switchTenant(tenantId);
},
),
),
);
}
}
Frontegg状态
FronteggPlugin
具有一个 FronteggState
,该状态根据插件的流程更改:
class FronteggState {
final String? accessToken;
final String? refreshToken;
final FronteggUser? user;
final bool isAuthenticated;
final bool isLoading;
final bool initializing;
final bool showLoader;
final bool appLink;
}
要获取 FronteggFlutter
的状态,有两种选择:
- 获取
currentState
:
@override
Widget build(BuildContext context) {
final frontegg = context.frontegg;
final fronteggState = frontegg.currentState;
}
- 监听
stateChanged
流:
import 'package:flutter/material.dart';
import 'package:frontegg_flutter/frontegg_flutter.dart';
import 'package:frontegg_flutter_example/login_page.dart';
import 'package:frontegg_flutter_example/user_page.dart';
class MainPage extends StatelessWidget {
const MainPage({super.key});
@override
Widget build(BuildContext context) {
final frontegg = context.frontegg;
return Scaffold(
body: Center(
child: StreamBuilder<FronteggState>(
stream: frontegg.stateChanged,
builder: (BuildContext context, AsyncSnapshot<FronteggState> snapshot) {
if (snapshot.hasData) {
final state = snapshot.data!;
if (state.isAuthenticated && state.user != null) {
return const UserPage();
} else if (state.initializing) {
return const CircularProgressIndicator();
} else {
return const LoginPage();
}
}
return const SizedBox();
},
),
),
);
}
}
其他frontegg功能
frontegg还为您提供以下功能:
logout
- 从FronteggFlutter
注销;refreshToken
- 仅在必要时刷新accessToken
和refreshToken
,如果刷新成功则返回true
;getConstants
- 返回Frontegg Flutter
初始化常量;directLoginAction
- 使用type
和data
直接登录;registerPasskeys
- 注册用户passkey;loginWithPasskeys
- 使用注册的用户passkey登录。requestAuthorize
- 使用刷新令牌和可选设备令牌Cookie请求授权。
已知问题
Android
如果您遇到 MissingPluginException
错误:
The following MissingPluginException was thrown while activating platform stream on channel frontegg_flutter/state_stream:
MissingPluginException(No implementation found for method listen on channel frontegg_flutter/state_stream)
请向 proguard-rules.pro
文件中添加以下行:
-keepclasseswithmembers class com.frontegg.** {*;}
更多关于Flutter前端管理与安全插件frontegg_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter前端管理与安全插件frontegg_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是一个关于如何在Flutter项目中集成和使用frontegg_flutter
插件的示例代码。frontegg_flutter
是一个用于前端管理和安全功能的Flutter插件,它可以帮助开发者轻松集成用户管理、身份验证、权限控制等功能。
步骤一:添加依赖
首先,在你的Flutter项目的pubspec.yaml
文件中添加frontegg_flutter
依赖:
dependencies:
flutter:
sdk: flutter
frontegg_flutter: ^最新版本号 # 请替换为实际的最新版本号
然后运行flutter pub get
来安装依赖。
步骤二:配置Frontegg
在你的Flutter应用的主文件中(通常是main.dart
),你需要配置和初始化frontegg_flutter
插件。
import 'package:flutter/material.dart';
import 'package:frontegg_flutter/frontegg_flutter.dart';
void main() {
// 初始化Frontegg
Frontegg.instance.init(
apiKey: '你的API_KEY', // 请替换为你的API Key
tenantId: '你的TENANT_ID', // 请替换为你的Tenant ID
env: '你的ENV', // 例如 'production' 或 'development'
config: {
// 你可以在这里添加其他配置参数
'someConfigKey': 'someConfigValue',
},
onInitSuccess: () {
// 初始化成功后的回调
print('Frontegg initialized successfully');
},
onInitError: (error) {
// 初始化失败后的回调
print('Failed to initialize Frontegg: $error');
},
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
@override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Flutter Demo Home Page'),
),
body: Center(
child: ElevatedButton(
onPressed: () {
// 打开Frontegg管理界面
Frontegg.instance.openWidget(context);
},
child: Text('Open Frontegg'),
),
),
);
}
}
步骤三:处理用户认证和权限
在实际应用中,你可能需要处理用户的认证和权限。frontegg_flutter
插件提供了与Frontegg服务交互的API,你可以使用这些API来处理用户的登录、注销和权限检查等操作。
以下是一个简单的示例,展示了如何使用frontegg_flutter
插件进行用户登录:
Future<void> loginUser(String email, String password) async {
try {
// 调用Frontegg的登录API
await Frontegg.instance.login(email: email, password: password);
print('User logged in successfully');
// 这里可以跳转到应用的主页面或其他逻辑
} catch (error) {
print('Failed to log in user: $error');
// 处理登录失败的情况,例如显示错误消息
}
}
你可以在按钮点击事件或其他适当的地方调用loginUser
函数:
ElevatedButton(
onPressed: () {
loginUser('user@example.com', 'password123');
},
child: Text('Login'),
),
注意
- 请确保你已经正确设置了Frontegg服务的API Key、Tenant ID和其他必要的配置。
- 根据你的应用需求,你可能需要调整Frontegg的配置和API调用。
frontegg_flutter
插件的API可能会随着版本的更新而变化,请参考官方文档以获取最新的API信息和最佳实践。
以上示例代码展示了如何在Flutter项目中集成和使用frontegg_flutter
插件进行前端管理和安全功能。希望这对你有所帮助!