跳到主要内容
Didit 融资 750 万美元,打造身份与欺诈基础设施
Didit
返回博客
博客 · 2026年7月28日

Flutter SDK:在您的应用中添加身份验证功能 (ZH)

一份开发者指南,介绍如何使用 Didit SDK 将身份验证添加到 Flutter 应用中:包括原生设置、后端创建会话、Dart 结果处理、类型化错误、Webhook、测试、安全性以及发布操作。.

作者:Didit更新于
flutter-sdk-identity-verification-integration-guide.png

Flutter SDK 身份验证集成应将永久凭据和最终授权保留在您的后端,而移动应用则使用短期会话令牌启动原生捕获流程。Didit Flutter SDK 在原生 iOS 和 Android 验证 SDK 之上公开了一个 Dart API,向应用返回类型化的完成、取消或失败结果。最终决策仍属于后端 Webhook 或检索流程。

本指南仅使用根据当前本地 SDK 源码和测试验证过的 Dart 方法和结果类型。原生依赖项的细节在不同版本之间会发生变化,因此平台配置通过职责进行描述,并链接到规范的 SDK 指南,而不是复制版本敏感的 Podfile 或 Gradle 块。

主要内容

  • 在后端创建生产会话。 将 API 密钥保留在设备之外,并且只发送 SDK 所需的会话令牌。
  • 使用类型化的 Dart 结果进行用户体验,而非授权。 VerificationCompleted 表示 SDK 流程结束;检查状态以进行显示,并等待权威的后端决策。
  • 单独处理取消、类型化失败和意外平台错误。 它们需要不同的恢复和分析。
  • 将原生设置视为发布基础架构。 iOS 隐私密钥、近场通信 (NFC) 权限、部署目标、Android 依赖项、打包和权限必须在真实设备上进行测试。
  • 设计完整的生命周期。 会话创建、应用交接、捕获、Webhook 验证、幂等状态更改、审查、重试和可观察性构成一个完整的集成。

Didit Flutter SDK 的作用

didit_sdk 包将原生 iOS 和 Android SDK 封装在一个共享的 Dart 接口后面。它将验证用户界面作为原生全屏流程启动,并在用户完成、取消或遇到错误时返回。

SDK 可以启动包含身份验证活体检测和其他已配置检查的工作流。工作流决定了哪些步骤出现;Flutter 调用不会对其进行硬编码。

与生命周期相关的公共 Dart 接口是:

DiditSdk.startVerification(token, config: ...)
DiditSdk.startVerificationWithWorkflow(workflowId, vendorData: ..., config: ...)

对于生产环境,首选使用后端创建的令牌的 startVerification。工作流 ID 方法更简单,但后端对高级参数的控制较少。

架构:后端、Flutter 应用、SDK 和 Webhook

生产流程有四个信任边界:

组件拥有不得拥有
您的后端API 密钥、工作流选择、客户参考、会话创建、最终客户状态摄像头界面
Flutter 应用交接请求、加载和恢复 UI、SDK 启动、本地分析永久 API 密钥或最终授权
Didit Flutter SDK原生捕获和已配置的验证流程您的产品授权决策
Webhook/检索工作器经过身份验证的结果摄取、去重、协调未经验证的客户端假设

顺序如下:

  1. 已登录的 Flutter 应用要求您的后端开始验证。
  2. 您的后端使用预期的工作流和稳定的内部客户参考创建验证会话。
  3. 后端将范围化的 session_token 返回给应用。
  4. 应用将该令牌传递给 DiditSdk.startVerification
  5. SDK 呈现原生流程并返回类型化结果以供即时用户体验。
  6. 您的后端接收并验证结果事件,协调规范状态,并根据您的策略更新客户。
  7. 应用在授予访问权限或声明最终批准之前读取您后端的客户状态。

此架构不信任设备上的成功屏幕。

有关服务器端契约和事件边界,请参阅身份验证 API 集成评估指南

安装包

使用包命令而不是复制可能过时的版本:

flutter pub add didit_sdk

然后导入公共库:

import 'package:didit_sdk/sdk_flutter.dart';

在升级之前,请阅读更改日志和官方 Flutter SDK 文档。对照您的应用和 CI 镜像检查声明的平台要求。

遵循 Flutter 发布说明中的原生依赖项;混合任意版本可能会导致不兼容。

配置 iOS 和 Android

iOS 职责

身份捕获可以使用受保护的硬件和数据。根据配置的工作流和 SDK 变体,iOS 设置可能需要:

  • 适当的部署目标;
  • 摄像头和麦克风使用说明;
  • 如果允许上传,则需要照片库使用说明;
  • 启用芯片读取时,需要 NFC 使用说明和权限;
  • 兼容的 CocoaPods 配置;
  • 与 NFC 使用匹配的签名功能和配置;
  • 如果配置了应用特定的字体,则需要注册自定义字体。

缺少隐私用途字符串可能会终止 iOS 应用。在物理设备上测试确切的工作流。

NFC 支持可能会提高最低部署目标或添加原生依赖项。选择与您的工作流匹配的 SDK 变体,并遵循当前文档中的 Podfile 配置。

Android 职责

在 Android 上,检查:

  • 最低 SDK 和 Java 要求;
  • 插件添加的存储库和依赖项;
  • 摄像头、网络和 NFC 清单条目;
  • 运行时摄像头权限行为;
  • Gradle 和 Kotlin 兼容性;
  • 原生或加密依赖项的打包规则;
  • allcoreautodetectionnfc SDK 变体;
  • 发布构建的缩小和资源行为。

您的产品仍然需要权限上下文、拒绝恢复、可访问性和支持说明。测试拒绝、中断、后台运行、旋转和进程重新创建。

在后端创建会话

您的后端应使用服务器端 API 密钥调用会话 API。将每个会话与以下内容关联:

  • 您的稳定客户标识符;
  • 选定的工作流;
  • 环境;
  • 适用的回调或返回行为;
  • 所需的区域设置或联系方式;
  • 策略使用时预期的客户详细信息;
  • 内部关联和策略元数据。

切勿将 Didit API 密钥嵌入 Dart、应用资产、可读的远程配置或移动请求中。

只返回会话令牌和最小启动状态。将其排除在分析、崩溃报告、日志、剪贴板使用和长期存储之外。

使启动请求幂等

客户可能会点击两次,在您的后端创建会话后失去连接,或者在尝试处于活动状态时重新打开屏幕。使用稳定的请求标识符和后端逻辑,返回现有适当的尝试,而不是创建不连贯的重复项。

您的应用的加载按钮应阻止明显的重复点击,但服务器端幂等性仍然是必要的,因为客户端会重试并且进程会重新启动。

从 Dart 开始验证

这个完整的 Dart 示例仅使用在包源中验证过的 SDK 导入、方法、结果类、会话字段、状态枚举和错误字段:

import 'package:didit_sdk/sdk_flutter.dart';

Future<void> runIdentityVerification(String sessionToken) async {
  try {
    final result = await DiditSdk.startVerification(
      sessionToken,
      config: const DiditConfig(
        loggingEnabled: false,
      ),
    );

    switch (result) {
      case VerificationCompleted(:final session):
        switch (session.status) {
          case VerificationStatus.approved:
            print('Flow completed with approved client status.');
          case VerificationStatus.pending:
            print('Flow completed and still needs a backend decision.');
          case VerificationStatus.declined:
            print('Flow completed with declined client status.');
        }
        print('Session ID: ${session.sessionId}');
        return;
      case VerificationCancelled():
        print('The user cancelled the verification flow.');
        return;
      case VerificationFailed(:final error):
        print('SDK error: ${error.type.name}: ${error.message}');
        return;
    }
  } catch (error, stackTrace) {
    print('Unexpected platform error: $error');
    print(stackTrace);
  }
}

该示例展示了类型结构。一个真实的应用应该更新屏幕状态并刷新后端状态,绝不能仅凭此函数解锁帐户。

为什么 VerificationCompleted 不总是批准

VerificationCompleted 包含 SessionData,其 status 是以下之一:

  • VerificationStatus.approved
  • VerificationStatus.pending
  • VerificationStatus.declined

SDK 流程可能在验证仍处于待处理或拒绝状态时完成。人工审查或异步检查也可能在应用调用返回后更改后端状态。将您的本地 UI 状态命名为“流程已完成”,而不是“身份已批准”,直到您的后端确认策略结果。

没有 Flutter 初始化调用

经过验证的公共 Flutter 接口没有公开独立的初始化方法。不要将 Android 原生初始化模式复制到 Dart 中。如果 Android 通过 Flutter 结果报告 notInitialized,请将其视为集成或原生桥接问题,并检查包设置。

处理类型化错误和恢复

SDK 验证过的错误类型是:

nody>
错误类型对应用策略的意义安全恢复
sessionExpired令牌不能再启动预期的会话向后端请求新的有效会话
networkError原生流程无法完成网络操作保留上下文并提供有限的重试
cameraAccessDenied所需的摄像头访问不可用解释其必要性并指导设置或替代路线
notInitializedAndroid 原生集成或桥接未准备就绪记录发布上下文并调查设置
apiErrorSDK 或服务返回 API 级别故障仅在安全时重试;协调后端状态
retryBlocked流程阻止另一次自动尝试停止循环并遵循后端或支持策略
unknown原生错误未映射到已知的 Dart 类型保留安全的回退和关联数据

原生平台可以公开不同的细节。保留一个 unknown 路径。

将错误与客户结果分开

网络故障不是拒绝;摄像头拒绝不是欺诈;取消不是身份失败。在以下类别中保持独立:

  • 用户消息;
  • 重试规则;
  • 产品访问;
  • 支持工具;
  • 分析;
  • 欺诈和转化报告。

有限重试

让后端决定现有会话是否可以继续,或者是否需要新会话。避免无限循环,该循环会重复使用已过期或被阻止的令牌调用 SDK。跟踪尝试次数和原因,而无需记录令牌或身份证据。

使用后端事件作为真相来源

SDK 返回一个紧凑的客户端结果。完整的证据和最终状态通过服务器端集成到达。您的 Webhook 处理程序应:

  1. 以文档中签名方案所需的形式接收原始请求;
  2. 验证事件并验证新鲜度;
  3. 对其事件标识符进行去重;
  4. 将其映射到预期的会话和客户;
  5. 防止旧事件覆盖后来的终端状态;
  6. 在需要协调时检索规范会话状态;
  7. 应用您的策略并保留原因;
  8. 在提供商的响应预算内返回;
  9. 异步处理缓慢的下游工作。

假设至少一次交付。重复和乱序事件是普通分布式系统行为。分别存储提供商事件和内部转换,以便审计可以重构两者。

应用应仅查询您的后端以获取其自己的产品状态,或使用您的常规实时通道。它不应公开提供商 API 密钥以直接检索最终记录。

构建弹性 Flutter 屏幕生命周期

显式建模本地状态

验证屏幕可以使用:

  • 空闲;
  • 请求会话;
  • 启动 SDK;
  • SDK 流程打开;
  • 协调后端决策;
  • 等待审核;
  • 已批准;
  • 已拒绝;
  • 可恢复错误;
  • 已取消。

只保留安全的内容。在进程死亡后,询问后端是否存在活动或已完成的会话。不要依赖内存中的布尔值来决定是否创建另一次尝试。

尊重小部件生命周期

在 awaited 调用之后,在 setState、对话框或导航之前检查 mounted。将业务状态保持在瞬态 UI 之外。

处理后台运行和取消

测试应用切换、屏幕锁定、导航和进程终止。定义恢复、重启和协调行为。

设计权限恢复

解释摄像头或 NFC 的需求。在永久拒绝后,显示设置指导或可访问的替代路线。

无策略泄露的配置

离线验证的 Flutter DiditConfig 接口公开了 languageCodefontFamilyloggingEnabledshowCloseButtonshowExitConfirmationcloseOnCompletedefaultDocumentCameradefaultLivenessCamerashowDocumentCameraSwitchButtonshowLivenessCameraSwitchButton。摄像头字段使用 CameraLens.frontCameraLens.back;所有选项都在 Dart 中类型化并映射到原生 SDK。

遵守三条规则:

  1. 仅在开发或受控诊断构建中启用详细日志记录;
  2. 不要将 UI 配置作为后端策略的替代品;
  3. 在两个平台上测试每种支持的语言、自定义字体、关闭行为和摄像头策略,包括当请求的镜头或资产不可用时的回退行为。

工作流组合和产品品牌属于控制台或后端管理的工作流,而不是移动功能标志的迷宫。这使得 iOS、Android、Web 和支持视图保持一致。

测试集成

Dart 和小部件测试

将 SDK 启动封装在应用程序服务后面,以便屏幕测试可以返回:

  • 已完成并已批准;
  • 已完成并待处理;
  • 已完成并已拒绝;
  • 已取消;
  • 每个类型化故障;
  • 意外抛出的平台异常。

断言加载状态清理、已挂载检查、重试可见性、后端刷新和分析类别。不要在夹具中放置真实的会话令牌。

原生集成测试

在物理 iOS 和 Android 设备上运行调试和发布版本。涵盖:

  • 首次和以前决定的权限;
  • 支持和不支持的摄像头;
  • NFC 启用和非 NFC 变体(如果使用);
  • 弱光、模糊、眩光和方向;
  • 慢速、丢失和恢复的连接;
  • 后台运行和进程重新创建;
  • 取消和重复启动;
  • 会话过期和重试阻止;
  • 不同的区域设置、字体缩放、屏幕阅读器和减少的运动;
  • 应用签名、缩小和生产依赖项解析。

模拟器对于状态和错误测试很有用,但不能代表每个摄像头、NFC、生物识别和设备完整性条件。

端到端后端测试

对每个文档化的客户状态使用确定性沙盒案例。重放已签名的测试事件,乱序发送重复项,延迟审查,并在模拟错过 Webhook 后进行协调。确认应用在您的后端状态更改之前绝不会授予访问权限。

有关生物识别测试设计和攻击边界,请参阅活体检测测试指南

安全和隐私清单

发布前,确认:

  • 永久提供商凭据仅存在于后端;
  • 应用通过经过身份验证的通道接收范围化的会话令牌;
  • 令牌和证据不存在于日志、分析、URL 和崩溃报告中;
  • 后端创建请求是幂等的,并与稳定的客户参考相关联;
  • 客户端完成绝不直接授予权限;
  • Webhook 签名、新鲜度、重复、排序和协调测试通过;
  • iOS 隐私描述和 Android 权限流程使用清晰的用途文本;
  • NFC 功能和变体与工作流和发布签名匹配;
  • 生产环境禁用调试日志记录;
  • 保留、同意、隐私声明、删除和支持路径与您的角色和法律相符;
  • 发布后监控 SDK、原生依赖项、操作系统和设备兼容性;
  • 回滚和强制升级决策有负责人。

常见的 Flutter SDK 集成错误

在 Dart 中发布 API 密钥

移动应用程序无法保护永久服务器凭据。在您的后端创建会话并传递范围化的令牌。

信任完成回调

客户端结果是用户界面状态。在后端确认权威状态并应用策略。

发明来自其他平台的方法

Flutter 不会以相同的名称公开每个原生 SDK 方法。在编写集成代码之前,请编译包并检查其公共 Dart 源代码。

复制过时的原生配置

SDK 变体、部署目标和包管理器设置会发生变化。遵循已安装版本的文档并在您的移动发布清单中记录。

将每个错误都视为拒绝

权限、网络、过期、API 故障、取消和客户决策需要不同的恢复和分析。

仅在模拟器上测试

摄像头、NFC、权限、签名和原生依赖项需要物理设备和发布版本覆盖。

在 Flutter 身份工作流中使用 Didit

Didit Flutter SDK 被列为免费。它可以启动包含身份验证活体检测和其他已配置检查的工作流,同时团队通过工作流编排器管理条件路径。

已发布的模块费率可在定价页面上找到。SDK 处理原生捕获体验;您的后端仍负责会话创建、经过身份验证的结果处理、客户状态和产品决策。

常见问题

哪个方法启动验证?

对于后端创建的生产会话,调用 DiditSdk.startVerification(sessionToken)。SDK 还公开了 DiditSdk.startVerificationWithWorkflow(...),用于更简单的工作流 ID 集成模式。

Flutter 应用是否应包含 Didit API 密钥?

不。将 API 密钥保留在后端。应用只应接收其验证尝试所需的范围化会话令牌。

VerificationCompleted 是否意味着已批准?

不一定。其会话状态可以是已批准、待处理或已拒绝。使用结果作为即时界面状态,并通过您的后端确认权威决策。

如何处理取消?

将其视为一个独特的客户结果。根据策略保留后端会话状态,提供清晰的恢复或重新启动路径,并且不要将取消标记为欺诈或拒绝。

Flutter SDK 是否有初始化方法?

经过验证的公共 Dart API 没有公开独立的初始化方法。遵循包的原生设置说明并使用文档中描述的启动方法。

Flutter 可以使用 NFC 进行身份文档验证吗?

当选定的包变体、设备、iOS 或 Android 配置、签名功能和工作流都启用 NFC 时,原生 SDK 可以支持 NFC。遵循当前发布文档并在物理设备上进行测试。

当案例正在审核中时,应用应该做什么?

显示真实的待处理状态,允许客户安全离开,并在收到经过身份验证的结果时从您的后端读取最终产品状态。

主要参考资料

强大的 Flutter SDK 集成使每个边界都明确:后端创建尝试,应用启动范围化的原生流程,类型化结果驱动恢复,经过身份验证的服务器事件驱动客户状态,以及真实设备测试证明权限、生命周期、原生依赖项和失败路径在“快乐路径”演示之外也能正常工作。

身份与欺诈基础设施。

一个 API 即可实现 KYC、KYB、交易监控和钱包筛选。5 分钟即可集成。

让 AI 总结此页面