Flutterアプリでの本人確認実装ガイド (JA)
FlutterアプリにDidit SDKで本人確認機能を追加するための開発者ガイド。ネイティブセットアップ、バックエンドで作成されたセッション、Dartでの結果処理、型付きエラー、Webhook、テスト、セキュリティ、リリース運用について解説します。.

本人確認のためのFlutter SDK統合では、一時的なセッショントークンでモバイルアプリがネイティブなキャプチャフローを開始する間、永続的な資格情報と最終的な承認はバックエンドに保持する必要があります。Didit Flutter SDKは、ネイティブのiOSおよびAndroid検証SDKの上に1つのDart APIを公開し、型付きの完了、キャンセル、または失敗の結果をアプリに返します。最終的な決定は、バックエンドのWebhookまたは取得フローに委ねられます。
このガイドでは、現在のローカルSDKソースとテストに対して検証されたDartメソッドと結果型のみを使用しています。ネイティブ依存関係の詳細はリリース間で変更されるため、プラットフォーム設定は責任別に説明され、バージョンに依存するPodfileやGradleブロックをコピーする代わりに、正規のSDKガイドにリンクされています。
重要なポイント
- バックエンドで本番セッションを作成します。 APIキーをデバイスから外し、SDKが必要とするセッショントークンのみを送信します。
- ユーザーエクスペリエンスには型付きのDart結果を使用し、承認には使用しないでください。
VerificationCompletedはSDKフローが終了したことを意味します。表示のためにステータスを検査し、信頼できるバックエンドの決定を待ちます。 - キャンセル、型付きの失敗、予期せぬプラットフォームエラーは個別に処理します。 これらには異なる回復と分析が必要です。
- ネイティブセットアップをリリースインフラストラクチャとして扱います。 iOSのプライバシーキー、近距離無線通信(NFC)エンタイトルメント、デプロイメントターゲット、Androidの依存関係、パッケージング、および権限は、実際のデバイスでテストする必要があります。
- ライフサイクル全体を設計します。 セッション作成、アプリのハンドオフ、キャプチャ、Webhook検証、冪等な状態変更、レビュー、再試行、およびオブザーバビリティは、1つの統合を形成します。
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
本番フローには4つの信頼境界があります。
| コンポーネント | 所有する | 所有してはいけない |
|---|---|---|
| お客様のバックエンド | APIキー、ワークフローの選択、顧客参照、セッション作成、最終的な顧客状態 | カメラインターフェース |
| Flutterアプリ | ハンドオフ要求、ロードおよび回復UI、SDK起動、ローカル分析 | 永続的なAPIキーまたは最終承認 |
| Didit Flutter SDK | ネイティブキャプチャおよび設定された検証フロー | お客様の製品の権限決定 |
| Webhook/取得ワーカー | 認証された結果の取り込み、重複排除、調整 | 未検証のクライアントの仮定 |
シーケンスは次のとおりです。
- サインインしたFlutterアプリは、本人確認を開始するようバックエンドに要求します。
- バックエンドは、意図したワークフローと安定した内部顧客参照を使用して検証セッションを作成します。
- バックエンドは、スコープ付きの
session_tokenをアプリに返します。 - アプリはそのトークンを
DiditSdk.startVerificationに渡します。 - SDKはネイティブフローを提示し、即時のユーザーエクスペリエンスのために型付きの結果を返します。
- バックエンドは結果イベントを受信して検証し、正規の状態を調整し、ポリシーに基づいて顧客を更新します。
- アプリは、アクセスを許可したり最終承認を主張したりする前に、バックエンドの顧客状態を読み取ります。
このアーキテクチャでは、デバイス上の成功画面を信頼しません。
サーバー側の契約とイベント境界については、本人確認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の互換性
- ネイティブまたは暗号化依存関係のパッケージングルール
all、core、autodetection、またはnfcSDKバリアント- リリースビルドのミニファイとリソースの動作
お客様の製品には、権限のコンテキスト、拒否からの回復、アクセシビリティ、およびサポート指示が依然として必要です。拒否、中断、バックグラウンド化、回転、およびプロセスの再作成をテストしてください。
バックエンドでのセッション作成
バックエンドは、サーバー側のAPIキーを使用してセッションAPIを呼び出す必要があります。各セッションを以下と関連付けます。
- 安定した顧客識別子
- 選択されたワークフロー
- 環境
- 該当する場合のコールバックまたは戻り動作
- ポリシーで必要とされる場合の必須ロケールまたは連絡先の詳細
- ポリシーで使用される場合の予期される顧客の詳細
- 内部相関およびポリシーメタデータ
Didit APIキーをDart、アプリのアセット、読み取り可能なリモート構成、またはモバイルリクエストに埋め込まないでください。
セッショントークンと最小限の起動状態のみを返します。分析、クラッシュレポート、ログ、クリップボードの使用、および長期保存から除外してください。
開始リクエストを冪等にする
顧客が2回タップしたり、バックエンドがセッションを作成した後に接続を失ったり、試行がアクティブなときに画面を再開したりする可能性があります。安定したリクエスト識別子と、切断された重複を作成するのではなく、既存の適切な試行を返すバックエンドロジックを使用してください。
アプリの読み込みボタンは明らかな繰り返しタップをブロックするはずですが、クライアントが再試行したりプロセスが再起動したりするため、サーバー側の冪等性は依然として必要です。
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.approvedVerificationStatus.pendingVerificationStatus.declined
SDKフローは、検証が保留中または拒否されたままであっても終了する可能性があります。人間のレビューや非同期チェックによって、アプリの呼び出しが戻った後にバックエンドの状態が変更されることもあります。バックエンドがポリシーの結果を確認するまでは、ローカルUIの状態を「本人確認承認済み」ではなく「フロー完了」と名付けてください。
Flutterの初期化呼び出しはありません
検証済みの公開Flutterサーフェスは、個別の初期化メソッドを公開していません。Androidネイティブの初期化パターンをDartにコピーしないでください。Flutterの結果を介してAndroidがnotInitializedを報告する場合は、統合またはネイティブブリッジの問題として扱い、パッケージのセットアップを検査してください。
型付きエラーの処理と回復
SDKの検証済みエラータイプは次のとおりです。
| エラータイプ | アプリポリシーにおける意味 | 安全な回復 |
|---|---|---|
sessionExpired | トークンは意図したセッションを開始できなくなりました | バックエンドに新しい有効なセッションを要求する |
networkError | ネイティブフローがネットワーク操作を完了できませんでした | コンテキストを保持し、制限付きの再試行を提供する |
cameraAccessDenied | 必要なカメラアクセスが利用できません | 必要な理由を説明し、設定または代替ルートを案内する |
notInitialized | Androidネイティブ統合またはブリッジが準備できていません | リリースコンテキストをログに記録し、セットアップを調査する |
apiError | SDKまたはサービスがAPIレベルの障害を返しました | 安全な場合にのみ再試行する。バックエンドの状態を調整する |
retryBlocked | フローが別の自動試行を妨げています | ループを停止し、バックエンドまたはサポートポリシーに従う |
unknown | ネイティブエラーが既知のDartタイプにマッピングされませんでした | 安全なフォールバックと相関データを保持する |
ネイティブプラットフォームは異なる詳細を公開する可能性があります。unknownパスを保持してください。
エラーと顧客の結果を区別する
ネットワーク障害は拒否ではありません。カメラの拒否は詐欺ではありません。キャンセルは本人確認の失敗ではありません。以下のカテゴリを区別してください。
- ユーザーメッセージ
- 再試行ルール
- 製品アクセス
- サポートツール
- 分析
- 不正行為およびコンバージョンレポート
再試行の制限
既存のセッションを続行できるか、新しいセッションが必要かをバックエンドに決定させます。期限切れまたはブロックされたトークンでSDKを繰り返し呼び出す無限ループを避けてください。トークンや本人確認の証拠をログに記録せずに、試行回数と原因を追跡します。
真実の情報源としてバックエンドイベントを使用する
SDKはコンパクトなクライアント結果を返します。完全な証拠と最終状態は、サーバー側の統合を通じて提供されます。Webhookハンドラーは次のことを行う必要があります。
- 文書化された署名スキームで要求される形式で生の要求を受信する
- イベントを認証し、鮮度を検証する
- そのイベント識別子を重複排除する
- それを予期されるセッションと顧客にマッピングする
- 古いイベントが後の最終状態を上書きするのを防ぐ
- 調整が必要な場合に、正規のセッション状態を取得する
- ポリシーを適用し、理由を永続化する
- プロバイダーの応答予算内で返す
- 遅いダウンストリーム作業を非同期で処理する
少なくとも1回の配信を前提とします。重複したイベントや順不同のイベントは、通常の分散システムの動作です。監査で両方を再構築できるように、プロバイダーイベントと内部トランジションを別々に保存します。
アプリは、独自の製品状態についてのみバックエンドをポーリングするか、通常のリアルタイムチャネルを使用する必要があります。最終レコードを直接取得するためにプロバイダーAPIキーを公開してはなりません。
回復力のあるFlutter画面ライフサイクルを構築する
明示的なローカル状態をモデル化する
検証画面では以下を使用できます。
- アイドル
- セッション要求中
- SDK起動中
- SDKフローオープン中
- バックエンド決定調整中
- レビュー待ち
- 承認済み
- 拒否済み
- 回復可能なエラー
- キャンセル済み
安全なものだけを永続化します。プロセスが終了した後、アクティブなセッションまたは終了したセッションが既に存在するかどうかをバックエンドに問い合わせます。別の試行を作成するかどうかを決定するために、インメモリのブール値に依存しないでください。
ウィジェットライフサイクルを尊重する
待機中の呼び出しの後、setState、ダイアログ、またはナビゲーションの前にmountedを確認します。ビジネス状態を一時的なUIの外に保ちます。
バックグラウンド処理とキャンセルを処理する
アプリの切り替え、画面ロック、ナビゲーション、プロセスの終了をテストします。再開、再起動、および調整の動作を定義します。
権限回復を設計する
カメラまたはNFCの必要性を説明します。永続的な拒否の後、設定ガイダンスまたはアクセシブルな代替ルートを表示します。
ポリシー漏洩のない設定
オフラインで検証されたFlutter DiditConfigサーフェスは、languageCode、fontFamily、loggingEnabled、showCloseButton、showExitConfirmation、closeOnComplete、defaultDocumentCamera、defaultLivenessCamera、showDocumentCameraSwitchButton、およびshowLivenessCameraSwitchButtonを公開します。カメラフィールドはCameraLens.frontまたはCameraLens.backを使用し、すべてのオプションはDartで型付けされ、ネイティブSDKにマッピングされます。
次の3つのルールを守ってください。
- 詳細なロギングは開発用または制御された診断ビルドでのみ有効にする
- UI設定をバックエンドポリシーの代替として使用しない
- サポートされている各言語、カスタムフォント、クローズ動作、およびカメラポリシーを、要求されたレンズまたはアセットが利用できない場合のフォールバック動作を含め、両方のプラットフォームでテストする
ワークフローの構成と製品のブランド化は、モバイルの機能フラグの迷宮ではなく、コンソールまたはバックエンド管理されたワークフローに属します。これにより、iOS、Android、Web、およびサポートビューが整合します。
統合のテスト
Dartとウィジェットテスト
SDKの起動をアプリケーションサービスの背後にラップして、画面テストが以下を返すようにします。
- 完了および承認済み
- 完了および保留中
- 完了および拒否済み
- キャンセル済み
- 各型付きの失敗
- 予期せぬスローされたプラットフォーム例外
ロード状態のクリーンアップ、マウントされたチェック、再試行の可視性、バックエンドの更新、および分析カテゴリをアサートします。フィクスチャに実際のセッショントークンを入れないでください。
ネイティブ統合テスト
物理的なiOSおよびAndroidデバイスでデバッグビルドとリリースビルドを実行します。以下をカバーします。
- 初回および以前に決定された権限
- サポートされているカメラとサポートされていないカメラ
- 使用されている場合はNFC対応および非NFCバリアント
- 低照度、ぼかし、グレア、および向き
- 遅い、失われた、復元された接続
- バックグラウンド処理とプロセスの再作成
- キャンセルと繰り返し起動
- セッションの期限切れと再試行のブロック
- 異なるロケール、フォントスケーリング、スクリーンリーダー、および削減されたモーション
- アプリの署名、ミニファイ、および本番依存関係の解決
エミュレーターは状態とエラーのテストには役立ちますが、すべてのカメラ、NFC、生体認証、およびデバイスの整合性条件を表すことはできません。
エンドツーエンドのバックエンドテスト
文書化された各顧客状態に対して決定論的なサンドボックスケースを使用します。署名されたテストイベントをリプレイし、順不同で重複を送信し、レビューを遅延させ、シミュレートされたWebhookの欠落後に調整します。バックエンドの状態が変更される前にアプリが決してアクセスを許可しないことを確認してください。
生体認証テストの設計と攻撃境界については、ライブネステストガイドを参照してください。
セキュリティとプライバシーチェックリスト
リリース前に、以下を確認してください。
- 永続的なプロバイダー資格情報がバックエンドのみに存在すること
- アプリが認証されたチャネルを介してスコープ付きセッショントークンを受信すること
- トークンと証拠がログ、分析、URL、およびクラッシュレポートに存在しないこと
- バックエンドの作成リクエストが冪等であり、安定した顧客参照に紐付けられていること
- クライアントの完了が直接エンタイトルメントを付与しないこと
- Webhookの署名、鮮度、重複、順序、および調整テストが合格すること
- iOSのプライバシー説明とAndroidの権限ジャーニーが明確な目的テキストを使用すること
- NFCの機能とバリアントがワークフローとリリース署名に一致すること
- 本番環境でデバッグロギングが無効になっていること
- 保持、同意、プライバシー通知、削除、およびサポートパスがお客様の役割と法律に一致すること
- SDK、ネイティブ依存関係、OS、およびデバイスの互換性が起動後に監視されること
- ロールバックと強制アップグレードの決定に責任者がいること
一般的なFlutter SDK統合の誤り
APIキーをDartに含めて出荷する
モバイルアプリケーションは永続的なサーバー資格情報を保護できません。バックエンドでセッションを作成し、スコープ付きトークンを渡してください。
完了コールバックを信頼する
クライアント結果はユーザーインターフェースの状態です。信頼できるステータスを確認し、バックエンドでポリシーを適用してください。
別のプラットフォームからメソッドを考案する
FlutterはすべてのネイティブSDKメソッドを同じ名前で公開しているわけではありません。統合コードを作成する前に、パッケージに対してコンパイルし、その公開Dartソースを確認してください。
古いネイティブ構成をコピーする
SDKのバリアント、デプロイメントターゲット、およびパッケージマネージャーのセットアップは変更されます。インストールされているリリースのドキュメントに従い、モバイルリリースチェックリストに記録してください。
すべてのエラーを拒否として扱う
権限、ネットワーク、期限切れ、API障害、キャンセル、および顧客の決定には、異なる回復と分析が必要です。
エミュレーターのみでテストする
カメラ、NFC、権限、署名、およびネイティブ依存関係には、物理デバイスとリリースビルドのカバーが必要です。
Flutter本人確認ワークフローでのDiditの使用
Didit Flutter SDKは無料でリストされています。これにより、本人確認、ライブネス検出、およびその他の設定されたチェックを含むワークフローを起動できます。一方、チームはワークフローオーケストレーターを通じて条件付きパスを管理します。
公開されているモジュール料金は料金ページで確認できます。SDKはネイティブのキャプチャ体験を処理しますが、セッション作成、認証された結果処理、顧客の状態、および製品の決定は引き続きお客様のバックエンドが担当します。
よくある質問
どのメソッドが検証を開始しますか?
バックエンドで作成された本番セッションの場合、DiditSdk.startVerification(sessionToken)を呼び出します。SDKは、よりシンプルなワークフローID統合モードのためにDiditSdk.startVerificationWithWorkflow(...)も公開しています。
FlutterアプリにDidit APIキーを含めるべきですか?
いいえ。APIキーはバックエンドに保持してください。アプリは、その検証試行に必要なスコープ付きセッショントークンのみを受け取るべきです。
VerificationCompletedは承認を意味しますか?
必ずしもそうではありません。セッションステータスは、承認済み、保留中、または拒否済みのいずれかです。即時のインターフェース状態には結果を使用し、信頼できる決定はバックエンドを通じて確認してください。
キャンセルはどのように処理すべきですか?
明確なユーザー結果として扱ってください。バックエンドのセッション状態を保持し、ポリシーに従って明確な再開または再試行パスを提供し、キャンセルを詐欺または拒否として分類しないでください。
Flutter SDKには初期化メソッドがありますか?
検証済みの公開Dart APIは、個別の初期化メソッドを公開していません。パッケージのネイティブセットアップ指示に従い、文書化された開始メソッドを使用してください。
Flutterは本人確認書類にNFCを使用できますか?
ネイティブSDKは、選択されたパッケージバリアント、デバイス、iOSまたはAndroidの設定、署名機能、およびワークフローのすべてがNFCを有効にしている場合に、NFCをサポートできます。現在のリリースドキュメントに従い、物理デバイスでテストしてください。
ケースがレビュー中の間、アプリは何をすべきですか?
真実の保留中の状態を表示し、顧客が安全に離れることを許可し、認証された結果が到着したときにバックエンドから最終的な製品状態を読み取ります。
主な参照資料
- Didit Flutter SDKドキュメント
- Didit Flutter SDKソースリポジトリ
- DiditセッションAPIドキュメント
- Didit Webhookドキュメント
- Flutterドキュメント:プラットフォーム統合
- OWASPモバイルアプリケーションセキュリティ検証標準
強力なFlutter SDK統合は、各境界を明示的に保ちます。バックエンドは試行を作成し、アプリはスコープ付きのネイティブフローを起動し、型付きの結果が回復を推進し、認証されたサーバーイベントが顧客の状態を推進し、実際のデバイステストが権限、ライフサイクル、ネイティブ依存関係、および失敗パスがハッピーパスのデモ以外で機能することを証明します。