Appearance
はじめに
QuickTrust API を使用して、本人確認(eKYC)機能をアプリケーションに統合する方法を説明します。
前提条件
- QuickTrust のテナントアカウント
- APIキー(管理者から発行)
- Webhookを受信可能なエンドポイント
基本的な流れ
QuickTrust の本人確認は以下のフローで動作します:
クイックスタート
1. 環境の準備
APIキーを環境変数に保存します。
bash
# .env
QUICK_TRUST_API_KEY=qt_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
QUICK_TRUST_API_BASE_URL=https://api.quicktrust.jpAPI エンドポイント
| 環境 | ベースURL |
|---|---|
| 本番環境 | https://api.quicktrust.jp |
| テスト環境 | https://api.staging.quicktrust.jp |
2. Verification Session の作成
ユーザーが本人確認を開始するときに、セッションを作成します。
bash
curl -X POST https://api.quicktrust.jp/v1/verification-sessions \
-H "Authorization: Bearer qt_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"callbackUrl": "https://your-app.com/verification/complete",
"clientIpAddress": "203.0.113.42"
}'Node.js での実装例:
javascript
async function createSession(userId, clientIp) {
const response = await fetch(`${API_BASE_URL}/v1/verification-sessions`, {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
callbackUrl: 'https://your-app.com/verification/complete',
clientIpAddress: clientIp,
}),
});
const { sessionId, verificationUrl } = await response.json();
// セッションとユーザーの紐付けを保存(重要)
await saveSessionMapping(userId, sessionId);
return { sessionId, verificationUrl };
}
// Express.js での使用例
app.post('/start-verification', async (req, res) => {
const clientIp =
req.headers['x-forwarded-for']?.split(',')[0] || req.socket.remoteAddress;
const { verificationUrl } = await createSession(req.user.id, clientIp);
res.redirect(verificationUrl);
});レスポンス:
json
{
"sessionId": "vs_abc123def456",
"verificationUrl": "https://client.quicktrust.jp/verify?sessionId=vs_abc123def456",
"verificationUrlExpiresAt": "2024-01-01T12:00:10Z",
"expiresAt": "2024-01-01T12:15:00Z"
}3. ユーザーを検証ページへリダイレクト
verificationUrl にユーザーをリダイレクトします。
Webアプリの例:
javascript
window.location.href = verificationUrl;モバイルアプリの例 (React Native):
javascript
import { Linking } from 'react-native';
Linking.openURL(verificationUrl);ユーザーは検証ページで以下のステップを完了します:
- 本人確認書類の選択
- 書類の撮影・アップロード
- Liveness検証(顔認証)
- 本人情報の入力(氏名、生年月日など)
4. Webhook で結果を受信
検証完了後、ユーザーは callbackUrl にリダイレクトされます。この時点ではバックグラウンドでの検証処理がまだ完了していない可能性があります。
最終的な検証結果は Webhook で受け取ってください:
javascript
// Webhook ハンドラー
app.post(
'/api/quicktrust/webhook',
express.raw({ type: 'application/json' }),
async (req, res) => {
// すぐにレスポンスを返す
res.status(200).send('OK');
const event = JSON.parse(req.body.toString());
const { verificationId, status } = event;
// verificationId は sessionId と同じ値
const userId = await getUserIdBySessionId(verificationId);
if (status === 'approved') {
await updateUserVerificationStatus(userId, 'verified');
} else if (status === 'rejected') {
await updateUserVerificationStatus(userId, 'rejected');
}
},
);詳細は Webhook ガイド を参照してください。
セッションの詳細設定
クライアントIPアドレス
clientIpAddress はセキュリティ上重要なパラメータです。QuickTrust は初回アクセス時にこのIPアドレスを検証し、セッション乗っ取りを防止します。
注意
現在 IPv6 アドレスはサポートしていません。IPv6 アドレスを指定した場合は無視されます。
javascript
// Express.js でクライアントIPを取得
const clientIp =
req.headers['x-forwarded-for']?.split(',')[0] || req.socket.remoteAddress;事前登録情報との照合
アプリケーション側で既にユーザー情報を持っている場合、preRegisteredInfo で送信できます。QuickTrust は OCR 結果とこの情報を照合し、一致/不一致を検証結果に含めます。
javascript
const response = await fetch(`${API_BASE_URL}/v1/verification-sessions`, {
method: 'POST',
headers: {
Authorization: `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
callbackUrl: 'https://your-app.com/verification/complete',
clientIpAddress: clientIp,
preRegisteredInfo: {
birthDate: '1990-01-01', // YYYY-MM-DD 形式
lastName: '山田',
firstName: '太郎',
address: '東京都渋谷区...', // 部分一致でも可
},
}),
});State パラメータ(CSRF対策)
プロキシや NAT 環境で IP アドレスが変動する場合、state パラメータを使用できます。
javascript
const state = crypto.randomUUID();
await saveStateToDatabase(userId, state);
const response = await fetch(`${API_BASE_URL}/v1/verification-sessions`, {
method: 'POST',
headers: {
/* ... */
},
body: JSON.stringify({
callbackUrl: 'https://your-app.com/verification/complete',
state: state,
// clientIpAddress は省略可能
}),
});
// コールバック受信時に state を検証
app.get('/verification/complete', async (req, res) => {
const { sessionId, state } = req.query;
const savedState = await getStateFromDatabase(userId);
if (state !== savedState) {
return res.status(403).send('Invalid state');
}
res.send('検証処理中です...');
});セッションIDとユーザーIDの紐付け
重要
セッション作成時に sessionId と userId を必ず紐付けて保存してください。Webhook で verificationId が返ってきたときに、どのユーザーの検証なのかを特定するために必要です。
verificationId は sessionId と同じ値です。
javascript
// セッション作成時
const { sessionId, verificationUrl } = await createSession(clientIp);
await db.saveSessionMapping(userId, sessionId);
// Webhook 受信時
async function handleWebhook(event) {
const { verificationId, status } = event;
const userId = await db.getUserIdBySessionId(verificationId);
// ...
}セッションの有効期限
| 項目 | 有効期限 | 説明 |
|---|---|---|
verificationUrl | 10秒 | URLの使い回しや傍受を防止 |
| セッション(Cookie設定後) | 15分 | 認証フロー完了まで |
ステータス一覧
セッションステータス
| ステータス | 説明 |
|---|---|
pending | セッション作成直後、ユーザーがまだアクセスしていない |
in_progress | ユーザーが検証ページにアクセス、画像アップロード中 |
liveness_success | Liveness検証完了、最終判定待ち |
completed | 全検証完了(承認/拒否/手動レビューの判定は Webhook で通知) |
expired | セッション有効期限切れ |
failed | 検証失敗(技術的な問題) |
検証結果ステータス
| ステータス | 説明 |
|---|---|
processing | 検証処理中 |
approved | 承認 |
rejected | 拒否 |
pending_review | 人間による審査が必要 |
セキュリティ
CORS対策
QuickTrust API はサーバーサイド専用です。ブラウザから直接呼び出すことはできません。
正しい: Browser → Your Server → QuickTrust API
間違い: Browser → QuickTrust API (CORS エラー)Callback URL のホワイトリスト
QuickTrust 側でコールバック URL のホワイトリストを管理します。テナント設定時に許可する URL を登録してください。
- 本番環境では HTTPS のみ許可
- 開発環境では
http://localhostも許可可能