本文へスキップ
Unveilydocs

生体認証

指紋と顔認証

概要

端末の指紋または顔認証を、ウェブページから JavaScript で呼び出します。Android と iOS の両方に対応しています。

機能AndroidiOS
指紋認証✓ BiometricPrompt(Android 7.0+)✓ Touch ID
顔認証✓ BiometricPrompt(Android 7.0+)✓ Face ID

対応プラン: Standard 以上(ライセンス機能 biometric が必要)

事前準備

Android

AndroidManifest.xml では生体認証権限がコメントアウトされた状態で配布されます。生体認証を使用するにはコメントを解除してください。

<uses-permission android:name="android.permission.USE_BIOMETRIC" />

iOS

Face ID を使用するには、Info.plistNSFaceIDUsageDescription キーを追加する必要があります。Face ID と Touch ID のどちらを使用するかは、デバイスのハードウェアに応じて自動的に決まります。

<key>NSFaceIDUsageDescription</key>
<string>本人確認のために Face ID を使用します。</string>

生体認証を実行する

unveilyBridge.auth.biometric(cb) を呼び出すと、システムの生体認証プロンプトが表示されます。cb は結果を受け取るコールバック関数名の文字列です。省略するとデフォルトの 'onBiometricResult' が使用されます。

// コールバック名を明示的に指定
window.unveilyBridge.auth.biometric("onBiometricResult");

// またはデフォルトのコールバック(onBiometricResult)を使用
window.unveilyBridge.auth.biometric();

function onBiometricResult(result) {
  if (result.success) {
    proceedWithSecureAction();       // 認証成功
    return;
  }
  if (result.cancelled) {
    return;                          // ユーザーがキャンセルした
  }
  // その他の失敗 — 未登録/未対応/プラン未対応などは error で渡される
  console.error("認証に失敗しました:", result.error);
  showPasswordFallback();
}

結果はすでにパースされた JS オブジェクトとして渡されます。JSON.parse() を呼び出す必要はありません。生体情報の未登録、ハードウェア未対応、プラン未充足などはすべて result.error メッセージで確認できます。

レスポンスの構造

コールバックは次の 3 つの形式のいずれかのオブジェクトを受け取ります。

{ "success": true }
{ "success": false, "cancelled": true }
{ "success": false, "error": "..." }
フィールド説明
success認証が成功したかどうか(true / false
cancelledユーザーがプロンプトをキャンセルすると true
error失敗理由のメッセージ(未登録/未対応/プラン未充足など)

サーバーセッションとの連携

生体認証が成功した後にサーバーでセッションを確定するパターンです。

function onBiometricResult(result) {
  if (result.success) {
    // サーバーに認証完了のシグナルを送る
    fetch('/api/auth/biometric-verified', { method: 'POST' })
      .then(() => window.location.href = '/secure-area');
  }
}
app.post('/api/auth/biometric-verified', (req, res) => {
  // すでにログイン済みのセッションで生体認証完了フラグを設定する
  if (!req.session.userId) {
    return res.status(401).json({ error: 'Not logged in' });
  }
  req.session.biometricVerified = true;
  res.json({ ok: true });
});
[HttpPost("auth/biometric-verified")]
[Authorize]
public IActionResult BiometricVerified()
{
    HttpContext.Session.SetString("BiometricVerified", "true");
    return Ok(new { ok = true });
}
@PostMapping("/api/auth/biometric-verified")
@PreAuthorize("isAuthenticated()")
public ResponseEntity<?> biometricVerified(HttpSession session) {
    session.setAttribute("biometricVerified", true);
    return ResponseEntity.ok(Map.of("ok", true));
}
<?php
session_start();
if (!isset($_SESSION['user_id'])) {
    http_response_code(401);
    exit(json_encode(['error' => 'Not logged in']));
}
$_SESSION['biometric_verified'] = true;
echo json_encode(['ok' => true]);
<%
If Session("user_id") = "" Then
    Response.Status = "401 Unauthorized"
    Response.End
End If
Session("biometric_verified") = True
Response.ContentType = "application/json"
Response.Write "{""ok"": true}"
%>

On this page