Flutter Keycloak认证管理插件keycloak_wrapper的使用
Flutter Keycloak认证管理插件keycloak_wrapper的使用
Keycloak Wrapper
通过这个插件,可以无缝地将 Keycloak Single Sign-On (SSO) 认证集成到您的Flutter应用程序中。该插件自动管理令牌,并提供一个用户认证状态流,使应用程序能够监听以保持与认证状态的变化同步。
Getting Started
关键点
- 该插件集成了 AppAuth SDK 来建立使用 OAuth 2.0 和 OpenID Connect (OIDC) 的连接。
- 使用 flutter_secure_storage 包来安全地存储所有令牌。
注意事项
- AndroidX 是必需的。
- 从 Android API 28 和 iOS 9 开始,默认禁用不安全的 HTTP 连接。如果需要允许明文连接,请参阅相关指南,但建议尽可能使用安全连接。
Keycloak 配置
前往您的 Keycloak Administration Console 并选择您的 Client ID,在访问设置部分插入 <bundle_identifier>:/
作为有效的重定向 URI 和登出重定向 URI。
Android 配置
在 build.gradle
文件中指定自定义方案:
android {
...
defaultConfig {
...
manifestPlaceholders += [
'appAuthRedirectScheme': '<package_name>'
]
}
}
确保 <package_name>
全为小写,且不要包含任何不允许出现在主机名中的字符。
iOS/macOS 配置
在 Info.plist
中指定自定义方案:
<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleTypeRole</key>
<string>Editor</string>
<key>CFBundleURLSchemes</key>
<array>
<string><bundle_identifier></string>
</array>
</dict>
</array>
Usage 示例代码
以下是一个完整的示例,展示了如何使用 keycloak_wrapper
插件:
import 'package:flutter/material.dart';
import 'package:keycloak_wrapper/keycloak_wrapper.dart';
final keycloakConfig = KeycloakConfig(
bundleIdentifier: 'com.example.demo',
clientId: '<client_id>',
frontendUrl: '<frontend_url>',
realm: '<realm>',
);
final keycloakWrapper = KeycloakWrapper(config: keycloakConfig);
final scaffoldMessengerKey = GlobalKey<ScaffoldMessengerState>();
void main() {
WidgetsFlutterBinding.ensureInitialized();
// 初始化插件
keycloakWrapper.initialize();
// 监听插件捕获的错误
keycloakWrapper.onError = (message, _, __) {
// 在snackbar中显示错误信息
scaffoldMessengerKey.currentState
?..hideCurrentSnackBar()
..showSnackBar(SnackBar(content: Text(message)));
};
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) => MaterialApp(
scaffoldMessengerKey: scaffoldMessengerKey,
// 监听用户认证状态流
home: StreamBuilder<bool>(
initialData: false,
stream: keycloakWrapper.authenticationStream,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
return const LoadingScreen();
} else if (snapshot.data!) {
return const HomeScreen();
} else {
return const LoginScreen();
}
},
),
);
}
class LoadingScreen extends StatelessWidget {
const LoadingScreen({super.key});
@override
Widget build(BuildContext context) => const Scaffold(
body: Center(
child: CircularProgressIndicator.adaptive(),
),
);
}
class LoginScreen extends StatelessWidget {
const LoginScreen({super.key});
// 登录
Future<void> login() async {
final isLoggedIn = await keycloakWrapper.login();
if (isLoggedIn) debugPrint('User has successfully logged in.');
}
@override
Widget build(BuildContext context) => Scaffold(
body: Center(
child: FilledButton(onPressed: login, child: const Text('Login')),
),
);
}
class HomeScreen extends StatelessWidget {
const HomeScreen({super.key});
// 登出
Future<void> logout() async {
final isLoggedOut = await keycloakWrapper.logout();
if (isLoggedOut) debugPrint('User has successfully logged out.');
}
@override
Widget build(BuildContext context) => Scaffold(
body: Center(
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
FutureBuilder(
future: keycloakWrapper.getUserInfo(),
builder: (context, snapshot) {
final userInfo = snapshot.data ?? {};
return Column(children: [
...userInfo.entries.map((entry) => Text('${entry.key}: ${entry.value}')),
if (userInfo.isNotEmpty) const SizedBox(height: 20),
]);
},
),
FilledButton(onPressed: logout, child: const Text('Logout')),
],
),
),
);
}
此示例展示了如何配置和使用 keycloak_wrapper
插件进行登录、获取用户信息、以及登出操作。请根据您的实际需求替换配置项中的占位符(如 <client_id>
、<frontend_url>
等)。
更多关于Flutter Keycloak认证管理插件keycloak_wrapper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
更多关于Flutter Keycloak认证管理插件keycloak_wrapper的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html
当然,以下是如何在Flutter项目中使用keycloak_wrapper
插件进行Keycloak认证管理的示例代码。这个插件通常用于与Keycloak服务器进行集成,以实现用户认证和授权。
首先,确保你已经将keycloak_wrapper
插件添加到你的Flutter项目中。在你的pubspec.yaml
文件中添加以下依赖项:
dependencies:
flutter:
sdk: flutter
keycloak_wrapper: ^最新版本号 # 替换为实际最新版本号
然后,运行flutter pub get
以安装依赖项。
示例代码
以下是一个基本的Flutter应用示例,展示了如何使用keycloak_wrapper
插件进行Keycloak认证。
1. 初始化Keycloak配置
创建一个新的Dart文件,比如keycloak_config.dart
,用于存储Keycloak服务器的配置信息。
// keycloak_config.dart
import 'package:keycloak_wrapper/keycloak_wrapper.dart';
class KeycloakConfig {
static final String realm = "your-realm";
static final String clientId = "your-client-id";
static final String url = "https://your-keycloak-server/auth";
static final KeycloakConfig instance = KeycloakConfig._();
KeycloakConfig._();
Keycloak getKeycloak() {
return Keycloak(
realm: realm,
clientId: clientId,
url: url,
);
}
}
2. 认证流程
在你的主应用文件(通常是main.dart
)中,使用keycloak_wrapper
插件进行认证。
// main.dart
import 'package:flutter/material.dart';
import 'package:keycloak_wrapper/keycloak_wrapper.dart';
import 'keycloak_config.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Keycloak? keycloak;
bool isAuthenticated = false;
@override
void initState() {
super.initState();
keycloak = KeycloakConfig.instance.getKeycloak();
// 尝试从存储中获取现有的token
keycloak!.onInit().then((isAuthenticated) {
setState(() {
this.isAuthenticated = isAuthenticated;
});
});
}
void login() async {
try {
bool authenticated = await keycloak!.login();
setState(() {
isAuthenticated = authenticated;
});
} catch (e) {
print("Login failed: $e");
}
}
void logout() async {
try {
bool loggedOut = await keycloak!.logout();
setState(() {
isAuthenticated = !loggedOut; // Logout should return true if successful
});
} catch (e) {
print("Logout failed: $e");
}
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Keycloak Auth Example'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text('Authenticated: $isAuthenticated'),
SizedBox(height: 20),
ElevatedButton(
onPressed: login,
child: Text('Login'),
),
SizedBox(height: 20),
ElevatedButton(
onPressed: logout,
child: Text('Logout'),
),
],
),
),
),
);
}
}
说明
-
KeycloakConfig:这是一个单例类,用于存储Keycloak服务器的配置信息,并返回一个配置好的
Keycloak
实例。 -
MyApp:这是Flutter应用的主类。在
initState
方法中,我们初始化keycloak
实例,并尝试从存储中获取现有的token。如果成功,将isAuthenticated
设置为true
。 -
login 和 logout 方法:这两个方法分别用于登录和注销。它们调用
keycloak
实例的login
和logout
方法,并更新isAuthenticated
状态。 -
UI:UI部分显示当前的认证状态,并提供登录和注销按钮。
这个示例展示了如何使用keycloak_wrapper
插件进行基本的Keycloak认证管理。根据你的实际需求,你可能需要进一步扩展这个示例,比如处理认证后的用户信息、刷新token等。