Flutter OpenID Connect认证插件openidconnect的使用

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

Flutter OpenID Connect认证插件openidconnect的使用

OpenIdConnect for Flutter

这是一个符合标准的OpenIdConnect库,专为Flutter设计,支持以下功能:

  1. Code flow with PKCE:这是隐式流的进化版。它允许弹出一个网页浏览器(已包含)进行身份验证,以连接到任何符合OpenID Connect标准的身份提供商(IdP)。
  2. Password flow:当您控制客户端和服务器,并希望用户直接登录到您的IdP时使用。
  3. Device flow:通常用于控制台应用程序等。目前在Windows、Linux和MacOS上使用,直到这些平台支持WebView。
  4. 完整的OpenIdConnect Client库:封装了整个过程,包括刷新令牌,刷新,并为您的应用程序发布事件流。

基础库支持大多数基本的OpenIdConnect功能:

  • 授权/登录(所有三种代码流)
  • 注销
  • 撤销令牌
  • 刷新令牌
  • 用户信息

此外,还有一个完整的OpenIdConnectClient,支持所有三种授权流,并自动维护登录信息的安全存储,并根据需要自动刷新令牌。

支持的平台

  • iOS
  • Android
  • Web
  • Windows
  • MacOS
  • Linux

Important

  1. 对于Linux、Windows和macOS,当前您的IdP必须支持设备代码流才能与交互式登录正常工作。否则,您必须使用密码流。这是因为这些环境尚未支持webView。
  2. 如果使用基础库,必须在使用前调用OpenIdConnect.InitializeEncryption(encryptionKey)。它必须是一个由您生成的16字符密钥。如果使用OpenIdConnectClient,则应提供自己的加密密钥,而不是依赖默认值。特别是如果您正在使用EncryptedSharedPreferences,它应该使用相同的密钥。

Getting Started

添加依赖

pubspec.yaml文件中添加openidconnect依赖:

dependencies:
  openidconnect: ^latest_version

初始化加密

确保调用initializeEncryption(如果您已经初始化了EncryptedSharedPreferences,则不需要再次调用):

import 'package:openidconnect/openidconnect.dart';

void main() {
  // Initialize encryption with a 16-character key
  OpenIdConnect.initializeEncryption('your_16_character_encryption_key');
  runApp(MyApp());
}

使用示例

以下是一个完整的示例,展示了如何使用openidconnect进行登录:

import 'package:flutter/material.dart';
import 'package:openidconnect/openidconnect.dart';
import 'package:openidconnect_example/choose.dart'; // 假设这是您自己的页面选择逻辑

void main() {
  // Initialize encryption with a 16-character key
  OpenIdConnect.initializeEncryption('your_16_character_encryption_key');
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  OpenIdConnectClient? _client;

  @override
  void initState() {
    super.initState();
    _initializeOpenIdConnect();
  }

  Future<void> _initializeOpenIdConnect() async {
    final config = OpenIdConfig(
      issuer: 'https://your-idp-url',
      clientId: 'your-client-id',
      clientSecret: 'your-client-secret', // Optional
      redirectUri: 'https://your-app-url/callback.html',
      scopes: ['openid', 'profile', 'email'],
    );

    _client = OpenIdConnectClient(config);
    await _client!.initialize();

    // Subscribe to events
    _client!.events.listen((event) {
      if (event is AuthorizationSuccessEvent) {
        print('Authorization successful!');
      } else if (event is AuthorizationFailureEvent) {
        print('Authorization failed: ${event.error}');
      }
    });
  }

  Future<void> _login() async {
    try {
      await _client!.authorize();
    } catch (e) {
      print('Login failed: $e');
    }
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('OpenID Connect Example'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: _login,
            child: Text('Login'),
          ),
        ),
      ),
    );
  }
}

Web 特殊处理

对于Web平台,您需要将callback.html文件从openidconnect_web复制到您的应用的web文件夹中。确保您的IdP具有正确的重定向路径https://{your_url_to_app/callback.html}作为接受的URL之一。

此外,Web平台有两套独立的交互式登录流程,具体取决于浏览器的安全限制。默认情况下,使用弹出窗口处理认证,这可以保持一切在进程中,而不需要重新加载Flutter应用程序。但是,如果您需要在点击按钮之外启动交互式登录,浏览器可能会阻止弹出窗口并提示用户允许它。因此,您可以设置useWebPopup = false来避免这种情况。

TODO

由于Flutter桌面支持的不断变化和不完整的插件实现,以下任务尚待完成:

  1. 在Android和iOS上使用自定义标签和安全认证弹窗,而不是WebView。
  2. 在Windows上使用安全认证弹窗(需要Tim Sneath在Windows上的Project Reunion集成和Dart的支持)。
  3. 在macOS和Linux上切换到WebView或至少在macOS上使用安全认证弹窗。
  4. 更多文档!

Contributing

欢迎提交Pull请求以修复任何发现的错误或解决上述TODO中的问题。如果您是C++、Kotlin或Swift开发者,特别欢迎您贡献自定义实现。

如果您添加了一个新的环境(除了Android和iOS),请遵循Flutter最佳实践,创建一个新的实现项目,并更新示例项目以使用新的实现。


通过以上内容,您可以开始在Flutter项目中使用openidconnect插件进行OpenID Connect认证。希望这些信息对您有所帮助!如果有任何问题,请随时提问。


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

1 回复

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


当然,以下是一个关于如何在Flutter应用中使用openid_connect插件进行OpenID Connect认证的代码示例。这个示例将展示如何初始化插件、执行认证流程以及处理认证结果。

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

dependencies:
  flutter:
    sdk: flutter
  openid_connect: ^x.y.z  # 请替换为最新版本号

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

接下来,在你的Flutter应用中,你可以按照以下步骤使用openid_connect插件:

1. 初始化OpenID Connect配置

创建一个配置类来存储OpenID Connect所需的配置信息,如授权服务器URL、客户端ID和重定向URI等。

import 'package:openid_connect/openid_connect.dart';

class OpenIdConfig {
  static final String authority = 'https://your-authorization-server.com';
  static final String clientId = 'your-client-id';
  static final String redirectUri = 'your-redirect-uri://callback';
  static final List<String> scopes = ['openid', 'profile', 'email'];
}

2. 创建OpenID Connect客户端

使用上述配置信息创建一个OidcClient实例。

import 'package:openid_connect/openid_connect.dart';

OidcClient oidcClient = OidcClient(
  authority: OpenIdConfig.authority,
  clientId: OpenIdConfig.clientId,
  redirectUri: Uri.parse(OpenIdConfig.redirectUri),
  scope: OpenIdConfig.scopes.join(' '),
);

3. 启动认证流程

在你的Flutter应用中,当用户需要登录时,启动认证流程。这通常是在一个按钮点击事件中完成的。

import 'package:flutter/material.dart';
import 'package:openid_connect/openid_connect.dart';
import 'package:url_launcher/url_launcher.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('OpenID Connect Demo'),
        ),
        body: Center(
          child: ElevatedButton(
            onPressed: () async {
              // 启动认证流程
              Uri loginUri = oidcClient.createAuthorizationUri();
              
              // 在移动设备上,通常需要使用url_launcher来打开浏览器
              if (await canLaunchUrl(loginUri)) {
                await launchUrl(loginUri);
              } else {
                throw 'Could not launch $loginUri';
              }
              
              // 注意:在实际应用中,你需要在应用内捕获重定向回调。
              // 这通常涉及在AndroidManifest.xml和Info.plist中配置自定义URL scheme,
              // 并在应用启动时检查该URL scheme。
              // 由于这是一个简单的示例,这里不展示回调处理。
            },
            child: Text('Login'),
          ),
        ),
      ),
    );
  }
}

4. 处理回调

在实际应用中,你需要处理认证后的回调。这通常涉及在应用启动时检查启动URI,并使用oidcClient.processResponse()方法来处理回调URI。

由于处理回调涉及平台特定的配置(如Android的AndroidManifest.xml和iOS的Info.plist),以及应用生命周期管理,这里不提供一个完整的示例。但你可以参考openid_connect插件的文档和示例项目来了解如何处理回调。

注意事项

  • 确保你的重定向URI在授权服务器上正确配置。
  • 在处理回调时,注意安全性,确保回调URI是由你的应用处理的,并且没有被篡改。
  • 在生产环境中,考虑使用更安全的存储方式来管理敏感信息,如客户端ID和重定向URI。

这个示例提供了一个基本的框架,你可以根据需要进行扩展和定制。希望这对你有所帮助!

回到顶部