跳到正文

sdk/flutter

适用于 iOS、Android 和桌面端的 Dart / Flutter SDK,使用 flutter_web_auth_2、PKCE S256 授权码流程和 flutter_secure_storage 进行 token 持久化。

状态

包状态为 已实现 · 本地已验证。纯 Dart 单元测试(21 个通过)覆盖 PKCE、token 模型和内存存储。平台通道路径(flutter_secure_storage、flutter_web_auth_2)需要真实设备或模拟器验证。IdP 往返验证待人工核实。本页面记录已实现的行为,不代表生产就绪声明。

安装

添加到 pubspec.yaml 并运行 flutter pub get:

# pubspec.yaml
dependencies:
  xid:
    git:
      url: https://github.com/StringKe/xid
      path: sdk/flutter
      ref: main

平台配置

在每个平台上注册 callback URI scheme。

<!-- Android: AndroidManifest.xml (main Activity) -->
<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="com.example.myapp" android:host="auth" />
</intent-filter>

<!-- iOS: Info.plist -->
<key>CFBundleURLTypes</key>
<array>
  <dict>
    <key>CFBundleURLSchemes</key>
    <array><string>com.example.myapp</string></array>
  </dict>
</array>

快速开始

import 'package:xid/xid.dart';

final client = XidClient();

// 1. Initialize (fetches OIDC discovery)
await client.configure(
  const XidOptions(
    issuer: 'https://xid.dev',
    clientId: 'YOUR_CLIENT_ID',
    redirectUri: 'com.example.myapp://auth/callback',
    scopes: ['openid', 'profile', 'email', 'offline_access'],
  ),
);

// 2. Sign in (opens system browser, PKCE S256)
final session = await client.signIn();
print(session.user.email);

// 3. Get valid access token (auto-refreshes)
final token = await client.getAccessToken();

// 4. Get current session
final current = await client.getSession();

// 5. Sign out (revokes refresh token + clears secure storage)
await client.signOut();

核心 API

方式 描述
configure(XidOptions, {storageAdapter?}) 初始化 SDK 并获取 OIDC discovery。必须在所有其他方法之前调用。
signIn({}additionalParameters?, audience?}) 以 PKCE S256 授权 URL 打开系统浏览器;交换 code 并返回 XidSession。
handleRedirect(String url) 处理 App Link 或自定义 scheme callback。由 signIn 内部调用;跨进程重定向恢复时手动调用。
getSession() 返回 XidSession?——如果访问令牌接近过期(60 秒内),触发 refresh token 轮换。
getAccessToken({}bool forceRefresh}) 返回有效的访问令牌字符串。传入 forceRefresh: true 可强制续期。
signOut({}bool openLogoutUrl}) 吊销 refresh token(RFC 7009),清除安全存储,并可选在浏览器中打开 end_session_endpoint。
setTokenStorage(TokenStorageAdapter) 用自定义实现替换默认的 SecureStorageAdapter(flutter_secure_storage)。

依赖项

版本 用途
flutter_web_auth_2 ^4.0.0 系统浏览器授权会话和 callback 接收
flutter_secure_storage ^9.2.4 平台安全存储(Keychain / Keystore / DPAPI)
crypto ^3.0.3 用于 PKCE S256 challenge 计算的 SHA-256
http ^1.2.2 用于 discovery 和 token 端点的 HTTP 客户端

安全

  • 公共客户端——不存储或传输客户端密钥。
  • 仅 PKCE S256。不支持 implicit 流程或 password grant。
  • 每次请求生成 OAuth state;在 handleRedirect 中验证以防 CSRF。
  • refresh token 存储在平台安全存储中(iOS 上为 Keychain,Android 上为 Keystore),并由 XID 服务器在每次使用时轮换。

已知限制

  • 基于 JWKS 的 ES256 ID token 验签、按 state 持久化的 PKCE 和 refresh single-flight 已实现并完成本地测试。真实设备和 IdP 验证前仍不具备 L4 支持。
  • 要接收 refresh token,scopes 中必须包含 offline_access。
导航

输入内容以搜索...

使用方向键导航按 Enter 键选择按 Escape 键关闭