Flutter Keycloak认证管理插件flutter_keycloak的使用

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

Flutter Keycloak认证管理插件flutter_keycloak的使用

flutter_keycloak 是一个用于在 Flutter 应用中管理 Keycloak 认证的插件。通过这个插件,你可以轻松地与 Keycloak 进行交互,处理用户的会话。

文档

  • [设置][SetupAnchor]
  • [API][APIAnchor]
  • [工具][UtilsAnchor]

设置

App 配置

导入

首先,导入 flutter_keycloak 插件并初始化:

import 'package:flutter_keycloak/flutter_keycloak.dart';

final FlutterKeycloak _flutterKeycloak = FlutterKeycloak();

API

登录

使用 login 方法进行用户登录:

void login() async {
  await _flutterKeycloak.login(
    _conf,
    _username,
    _password,
    scope: _scope,
  );
}

有时你可能需要重新登录用户,但不想显示登录页面。这种情况下可以使用此方法重新登录用户。

刷新登录

使用 refreshLogin 方法刷新用户的登录状态:

void refreshLogin() async {
  await _flutterKeycloak.refreshLogin(
    scope: 'offline_access',
  );
}

获取用户信息

使用 retrieveUserInfo 方法获取当前登录用户的信息:

void retrieveUserInfo() async {
  final userInfo = await _flutterKeycloak.retrieveUserInfo();
  setState(() {
    _currentPrefs = userInfo.toString();
  });
}

注销

使用 logout 方法注销当前用户:

void logout() async {
  await _flutterKeycloak.logout();
  printStorage();
}

注意destroySession 参数用于控制是否销毁 Keycloak 侧的会话。如果使用 login 方法,建议传递 false。传递 true 会尝试销毁会话,但在较新的 Keycloak 版本中,如果没有会话存在,这将导致错误,从而阻止注销操作。

示例代码

以下是一个完整的示例代码,展示了如何在 Flutter 应用中使用 flutter_keycloak 插件:

import 'package:flutter/material.dart';
import 'package:flutter_keycloak/flutter_keycloak.dart';
import 'package:flutter_keycloak/token_storage.dart';
import 'package:get_storage/get_storage.dart';

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

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Keycloak Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const FlutterKeycloakExample('Flutter Keycloak Example'),
    );
  }
}

class FlutterKeycloakExample extends StatefulWidget {
  final String title;

  const FlutterKeycloakExample(this.title, {Key? key}) : super(key: key);

  @override
  FlutterKeycloakExampleState createState() => FlutterKeycloakExampleState();
}

class FlutterKeycloakExampleState extends State<FlutterKeycloakExample> {
  final FlutterKeycloak _flutterKeycloak = FlutterKeycloak();
  late final TextEditingController _confController;
  late final TextEditingController _usernameController;
  late final TextEditingController _passwordController;
  late final TextEditingController _scopeController;

  String _currentPrefs = '';
  Map? _conf;

  @override
  void initState() {
    GetStorage.init();
    _confController = TextEditingController();
    _usernameController = TextEditingController();
    _passwordController = TextEditingController();
    _scopeController = TextEditingController();
    super.initState();
  }

  @override
  void dispose() {
    _confController.dispose();
    _usernameController.dispose();
    _passwordController.dispose();
    _scopeController.dispose();
    super.dispose();
  }

  void printStorage() {
    getCredentials().then((credentials) {
      setState(() {
        _currentPrefs =
            '${getConfiguration()}\n\n${getTokens()}\n\n$credentials';
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Padding(
        padding: const EdgeInsets.all(8.0),
        child: Center(
          child: _conf != null
              ? ListView(
                  children: [
                    Row(
                      children: [
                        Expanded(
                          child: TextFormField(
                            controller: _usernameController,
                            decoration: const InputDecoration(hintText: 'Username'),
                          ),
                        ),
                        const SizedBox(width: 20),
                        Expanded(
                          child: TextFormField(
                            controller: _passwordController,
                            decoration: const InputDecoration(hintText: 'Password'),
                          ),
                        ),
                        const SizedBox(width: 20),
                        Expanded(
                          child: TextFormField(
                            controller: _scopeController,
                            decoration: const InputDecoration(hintText: 'Scope'),
                          ),
                        ),
                      ],
                    ),
                    ElevatedButton(
                      onPressed: () async {
                        await _flutterKeycloak.login(
                          _conf,
                          _usernameController.text,
                          _passwordController.text,
                          scope: _scopeController.text.isNotEmpty
                              ? _scopeController.text
                              : 'offline_access',
                        );
                        printStorage();
                      },
                      child: const Text('LOGIN'),
                    ),
                    ElevatedButton(
                      onPressed: () async {
                        final userInfo = await _flutterKeycloak.retrieveUserInfo();
                        setState(() {
                          _currentPrefs = userInfo.toString();
                        });
                      },
                      child: const Text('GET USER INFO'),
                    ),
                    ElevatedButton(
                      onPressed: () async {
                        await _flutterKeycloak.refreshLogin(
                          scope: 'offline_access',
                        );
                        printStorage();
                      },
                      child: const Text('REFRESH LOGIN'),
                    ),
                    ElevatedButton(
                      onPressed: () async {
                        await _flutterKeycloak.refreshToken();
                        printStorage();
                      },
                      child: const Text('REFRESH TOKEN'),
                    ),
                    ElevatedButton(
                      onPressed: () async {
                        await _flutterKeycloak.logout();
                        setState(() {
                          _currentPrefs = '';
                        });
                      },
                      child: const Text('LOGOUT'),
                    ),
                    if (_currentPrefs.isNotEmpty) Text(_currentPrefs),
                  ],
                )
              : Column(
                  children: [
                    TextFormField(
                      controller: _confController,
                      decoration: const InputDecoration(hintText: 'Type here the config url'),
                    ),
                    ElevatedButton(
                      onPressed: () => _flutterKeycloak
                          .getConf(_confController.text)
                          .then((conf) => setState(() => _conf = conf)),
                      child: const Text('GET CONF AND PROCEED'),
                    ),
                  ],
                ),
        ),
      ),
    );
  }
}

这个示例展示了如何配置和使用 flutter_keycloak 插件来处理 Keycloak 的登录、获取用户信息、刷新登录和注销等操作。希望对你有所帮助!


更多关于Flutter Keycloak认证管理插件flutter_keycloak的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter Keycloak认证管理插件flutter_keycloak的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是如何在Flutter应用中使用flutter_keycloak插件进行Keycloak认证的代码示例。这个插件可以帮助你轻松集成Keycloak身份验证功能。

首先,确保你已经在pubspec.yaml文件中添加了flutter_keycloak依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_keycloak: ^latest_version  # 请替换为最新版本号

然后运行flutter pub get来安装依赖。

接下来,你需要在Flutter应用中配置Keycloak客户端信息。通常,这些信息包括Keycloak服务器的URL、客户端ID、客户端密钥以及重定向URI。以下是一个简单的示例,展示如何配置和使用flutter_keycloak插件。

1. 配置Keycloak客户端信息

创建一个keycloak_config.dart文件来存储Keycloak的配置信息:

import 'package:flutter_keycloak/flutter_keycloak.dart';

class KeycloakConfig {
  static final KeycloakConfig _singleton = KeycloakConfig._internal();

  factory KeycloakConfig() => _singleton;

  KeycloakConfig._internal();

  Keycloak get keycloak => Keycloak(
    realm: 'your-realm',
    url: 'https://your-keycloak-server/auth',
    clientId: 'your-client-id',
    clientSecret: 'your-client-secret', // 注意:在移动应用中通常不会使用clientSecret,这里仅为演示
    redirectUri: 'your-redirect-uri://callback', // 确保在Keycloak客户端配置中添加了此URI
  );
}

2. 初始化Keycloak并处理认证

在你的主应用文件(例如main.dart)中,初始化Keycloak并进行认证:

import 'package:flutter/material.dart';
import 'package:flutter_keycloak/flutter_keycloak.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().keycloak;
    keycloak!.init().then((_) async {
      bool authenticated = await keycloak!.isAuthenticated();
      if (!authenticated) {
        // 用户未认证,跳转到登录页面
        await keycloak!.login();
        authenticated = await keycloak!.isAuthenticated();
      }
      setState(() {
        isAuthenticated = authenticated;
      });
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Flutter Keycloak Example'),
        ),
        body: Center(
          child: isAuthenticated
              ? Text('User is authenticated')
              : Text('User is not authenticated'),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () async {
            if (isAuthenticated) {
              await keycloak!.logout();
              setState(() {
                isAuthenticated = false;
              });
            } else {
              // 用户已登出,这里可以重新登录或进行其他操作
            }
          },
          tooltip: 'Toggle Authentication',
          child: Icon(isAuthenticated ? Icons.logout : Icons.login),
        ),
      ),
    );
  }
}

3. 配置Android和iOS重定向URI

确保在你的AndroidManifest.xml和iOS项目中正确配置了重定向URI。对于Android,你可能需要在AndroidManifest.xml中添加一个intent-filter。对于iOS,你需要在Info.plist中添加一个自定义URL scheme。

Android

AndroidManifest.xml中添加:

<activity
    android:name=".MainActivity"
    android:launchMode="singleTop"
    android:theme="@style/LaunchTheme"
    android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|screenLayout|density|uiMode"
    android:hardwareAccelerated="true"
    android:windowSoftInputMode="adjustResize">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="your-redirect-uri" android:host="callback" />
    </intent-filter>
</activity>

iOS

Info.plist中添加:

<key>CFBundleURLTypes</key>
<array>
    <dict>
        <key>CFBundleURLSchemes</key>
        <array>
            <string>your-redirect-uri</string>
        </array>
    </dict>
</array>

总结

以上代码示例展示了如何在Flutter应用中使用flutter_keycloak插件进行Keycloak认证管理。通过配置Keycloak客户端信息、初始化Keycloak并进行认证,你可以轻松地在Flutter应用中集成Keycloak身份验证功能。记得根据你的实际需求调整代码和配置。

回到顶部