Flutter集成Parse Server OpenID插件parseserver_openid_flutter的使用

Flutter集成Parse Server OpenID插件parseserver_openid_flutter的使用


Parse Logo


pub.dev version pub.dev prerelease

此包为parse_server_sdk_flutter包增加了OpenID认证功能。

通过与访问服务器进行身份验证并发送访问令牌到Parse服务器,客户端会收到一个sessionToken。之后,该sessionToken用于对Parse服务器进行身份验证。

有多种场景需要Parse服务器与中央OpenID服务器进行认证:

  1. 您已经有一个带有中央认证服务器的应用网络(例如,KeyCloak)。
  2. 您希望在不同的(Web)应用之间提供单点登录(SSO)。
  3. 您希望拥有一个灵活的用户数据库以方便未来的扩展。

开始使用

添加包

你必须将此包添加到项目的pubspec.yaml文件中。

dependencies:
  parseserver_openid_flutter: ">=0.2.0 <0.3.0"
平台特定设置

为了在原生应用中接收重定向链接,你需要设置uni_links

Android

android/app/src/main/AndroidManifest.xml中添加一个新的意图过滤器;

<manifest ...>
  <!-- ... 其他标签 -->
  <application ...>
    <activity ...>
      <!-- ... 其他标签 -->

      <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:scheme="com.example.parseopenid"
            android:host="parseopenid.example.com"/>
      </intent-filter>
    </activity>
  </application>
</manifest>

如果你的目标是Android 30或以上版本,还需要在android/app/src/main/AndroidManifest.xml中添加以下内容。否则,你的应用不允许在浏览器中打开http链接。

<manifest ...>
    <queries>
    <intent>
      <action android:name="android.intent.action.VIEW" />
      <category android:name="android.intent.category.BROWSABLE" />
      <data android:scheme="https" />
    </intent>
  </queries>
</manifest>
iOS

ios/Runner/Info.plist中添加CFBundleURLTypes键。

<?xml ...?>
<!-- ... 其他标签 -->
<plist>
<dict>
  <!-- ... 其他标签 -->
  <key>CFBundleURLTypes</key>
  <array>
    <dict>
      <key>CFBundleTypeRole</key>
      <string>Editor</string>
      <key>CFBundleURLName</key>
      <string>parseopenid.example.com</string>
      <key>CFBundleURLSchemes</key>
      <array>
        <string>com.example.parseopenid</string>
      </array>
    </dict>
  </array>
  <!-- ... 其他标签 -->
</dict>
</plist>
静态网页

为了在网页上接收授权响应,你需要将openidredirect.html文件添加到web/目录下。 显然,你可以调整这个文件。但确保保留window.opener.postMessage(window.location.href, '*');这一行。

添加云函数

由于此包不使用Parse服务器第三方授权,你需要将此云函数添加到你的云代码中。

注意:请务必检查这部分是否更新,因为你更改了此包的版本。

初始化ParseOpenID

在哪里初始化Parse(),你也想初始化ParseOpenID()

// 这些是本地KeyCloak安装的值
initParse() {
  Parse parse = Parse();
  parseOpenID = ParseOpenID(
    authorizationEndpoint: Uri.parse(
        "https://192.168.178.65:8443/auth/realms/master/protocol/openid-connect/auth"),
    tokenEndpoint: Uri.parse(
        "https://192.168.178.65:8443/auth/realms/master/protocol/openid-connect/token"),
    redirectPath: "openidredirect.html",
    redirectHost: "parseopenid.example.com",
    redirectScheme: "com.example.parseopenid",
    clientID: "flutter",
    parse: parse,
    logoutEndpoint:
        "https://192.168.178.65:8443/auth/realms/master/protocol/openid-connect/logout",
  );
  parse
      .initialize(
        "myappID",
        "http://192.168.178.65:1337/parse",
      )
      .then((parse) => parseOpenID.init());
}
使用OpenID进行身份验证

就是这样!

你应该现在能够登录和登出。

/// 登录到Parse
Future<void> login() => ParseOpenID().login();

/// 从Parse登出
Future<void> logout() => ParseOpenID().logout();

完整示例代码

import 'dart:io';

import 'package:flutter/material.dart';
import 'package:parse_server_sdk_flutter/parse_server_sdk.dart';
import 'package:parseserver_openid_flutter/parseserver_openid_flutter.dart';

const HOST_IP = "192.168.178.65";

void main() {
  HttpOverrides.global = new MyHttpOverrides();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);
  final String title;

  [@override](/user/override)
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  ParseOpenID parseOpenID;

  _MyHomePageState() {
    Parse parse = Parse();
    parseOpenID = ParseOpenID();
    parse
        .initialize(
          "myappID",
          "http://$HOST_IP:1337/parse",
        )
        .then((parse) => parseOpenID.init(
              authorizationEndpoint:
                  "https://$HOST_IP:8443/auth/realms/master/protocol/openid-connect/auth",
              tokenEndpoint:
                  "https://$HOST_IP:8443/auth/realms/master/protocol/openid-connect/token",
              redirectPath: "openidredirect.html",
              redirectHost: "parseopenid.example.com",
              redirectScheme: "com.example.parseopenid",
              clientID: "flutter",
              parse: parse,
              logoutEndpoint:
                  "https://$HOST_IP:8443/auth/realms/master/protocol/openid-connect/logout",
            ));
  }

  [@override](/user/override)
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.center,
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            StreamBuilder<AuthenticationState>(
              stream: parseOpenID.stateStream,
              builder: (context, snapshot) => Text(snapshot.data.toString()),
            ),
            OutlinedButton(
              onPressed: () async {
                authenticate();
              },
              child: Text("登录"),
            ),
            OutlinedButton(
              onPressed: () async {
                parseOpenID.logout();
              },
              child: Text("登出"),
            )
          ],
        ),
      ),
    );
  }

  authenticate() async {
    parseOpenID.login();
  }
}

class MyHttpOverrides extends HttpOverrides {
  [@override](/user/override)
  HttpClient createHttpClient(SecurityContext context) {
    return super.createHttpClient(context)
      ..badCertificateCallback =
          (X509Certificate cert, String host, int port) => true;
  }
}

更多关于Flutter集成Parse Server OpenID插件parseserver_openid_flutter的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter集成Parse Server OpenID插件parseserver_openid_flutter的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,下面是一个关于如何在Flutter项目中集成并使用parseserver_openid_flutter插件的示例代码。这个插件允许你通过Parse Server实现OpenID Connect身份验证。

1. 添加依赖

首先,在你的pubspec.yaml文件中添加parseserver_openid_flutter依赖:

dependencies:
  flutter:
    sdk: flutter
  parseserver_openid_flutter: ^最新版本号  # 请替换为实际的最新版本号

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

2. 配置Parse Server

确保你的Parse Server已经配置了OpenID Connect。这通常涉及到设置一些环境变量,比如PARSE_SERVER_OPENID_ISSUERPARSE_SERVER_OPENID_CLIENT_IDPARSE_SERVER_OPENID_CLIENT_SECRET

3. 初始化Parse Server客户端

在你的Flutter应用的主文件中(通常是main.dart),初始化Parse Server客户端并配置OpenID Connect:

import 'package:flutter/material.dart';
import 'package:parseserver_openid_flutter/parseserver_openid_flutter.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text('Parse Server OpenID Example'),
        ),
        body: Center(
          child: ParseOpenIDDemo(),
        ),
      ),
    );
  }
}

class ParseOpenIDDemo extends StatefulWidget {
  @override
  _ParseOpenIDDemoState createState() => _ParseOpenIDDemoState();
}

class _ParseOpenIDDemoState extends State<ParseOpenIDDemo> {
  final ParseClient parseClient = ParseClient(
    server: 'https://你的ParseServer地址/parse', // 替换为你的Parse Server地址
    appId: '你的AppId',
    clientKey: '你的ClientKey',
    liveQueryUrl: 'wss://你的ParseServer地址/parse', // 如果使用LiveQuery
  );

  @override
  void initState() {
    super.initState();
    // 初始化Parse客户端
    parseClient.initialize().then((value) {
      print('Parse Client Initialized');
    }).catchError((error) {
      print('Error initializing Parse Client: $error');
    });
  }

  Future<void> _loginWithOpenID() async {
    try {
      // 这里假设你已经有了OpenID Connect所需的token等信息
      final Map<String, String> authData = {
        'openid': {
          'id_token': '用户的ID Token', // 替换为实际的ID Token
          'access_token': '用户的Access Token', // 替换为实际的Access Token
          'expires_in': 'token过期时间(秒)', // 替换为实际的过期时间
        },
      };

      final ParseUser user = await parseClient.loginWith(authData: authData);
      print('User logged in: ${user.toJson()}');
    } catch (error) {
      print('Error logging in with OpenID: $error');
    }
  }

  @override
  Widget build(BuildContext context) {
    return ElevatedButton(
      onPressed: _loginWithOpenID,
      child: Text('Login with OpenID'),
    );
  }
}

4. 运行应用

确保你的Parse Server正在运行,并且已经正确配置了OpenID Connect。然后运行你的Flutter应用,点击按钮尝试使用OpenID Connect进行登录。

注意事项

  1. 安全性:不要在客户端代码中硬编码敏感信息,比如clientKeyaccess_token等。这些信息应该从安全的后端服务获取。
  2. 错误处理:示例代码中的错误处理非常基础,实际项目中应该添加更详细的错误处理和用户反馈。
  3. 依赖版本:确保你使用的是parseserver_openid_flutter插件的最新稳定版本。

通过上述步骤,你应该能够在Flutter应用中成功集成并使用parseserver_openid_flutter插件进行OpenID Connect身份验证。

回到顶部