본문으로 건너뛰기
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 메시지로 확인할 수 있습니다.

응답 구조

콜백은 다음 세 가지 형태 중 하나의 객체를 받습니다.

{ "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