완전한 ID check 온보딩 가이드
이 종합 가이드는 ARGOS ID check를 이용해 처음 시작부터 운영 환경까지 나아가는 전 과정을 안내합니다. 신원 확인(Identity Verification)에 처음인 개발자든, 다른 솔루션에서 마이그레이션 중이든, 이 문서만으로 필요한 모든 내용을 파악할 수 있습니다.
완료 예상 시간 : 기본 통합 30–45분, 고급 기능 포함 2–3시간사전 준비물 :
ARGOS Identity 계정 (여기에서 가입 )
REST API에 대한 기본 지식
인터넷에 연결된 개발 환경
파트 1: 기초 ID check 이해, 계정 설정, 핵심 개념
파트 2: 통합 Liveform 및 API 연동 방법
파트 1: 기초
ARGOS ID check란?
ARGOS ID check는 AI 기반 문서 검증 에 사기 탐지 와 컴플라이언스 기능을 결합한 종합 신원 인증 플랫폼입니다.
핵심 기능:
문서 검증 여권, 운전면허증, 국가 신분증, 거주 허가 등 전 세계 200+개 국가의 20+ 문서 유형을 검증
데이터 추출 신분증에서 정보를 자동 추출·구조화 (정확도 98%+)
사기 탐지 위조, 사진 대체, 문서 변조를 AI로 감지
컴플라이언스 KYC/AML 준수 내장, 검증 규칙 커스터마이즈 및 감사 추적(Audit Trail) 제공
동작 방식:
사용자 문서 제출
사용자는 Liveform URL 또는 커스텀 UI를 통해 신분증 사진을 업로드합니다.
AI 분석
ARGOS AI 엔진이 문서 진위 여부를 분석하고, 데이터 필드를 추출하며, 생체 검증(활동성) 체크를 수행합니다.
검증 결정
설정한 규칙에 따라 자동 승인/거절되거나, 수동 심사 대상으로 플래그됩니다.
결과 전달
구조화된 검증 결과가 웹훅과 API로 전달되며 전체 감사 추적이 포함됩니다.
계정 생성 및 대시보드 둘러보기
이제 계정을 만들고 대시보드에 익숙해져 봅시다.
대시보드 탐색
주요 메뉴:
Submissions : 모든 검증 제출 내역 조회 및 관리
Settings : 프로젝트 설정, 웹훅, 보안 구성
Access Management : API 키, Liveform URL, IP 화이트리스트
Analytics : 검증 지표와 성공률 추적
Project Settings : 검증 규칙, 문서 유형, 정책
API 자격 증명 확인
Settings → Access Management 로 이동:
API Key : API 요청 인증에 사용하는 키(철저히 보관)
Project ID (PID) : 프로젝트 고유 식별자
Liveform URL : 호스팅되는 검증 페이지 URL
API Key: argos_live_abc123xyz...
Project ID: pid_abc123
Liveform URL: https://form.argosidentity.com?pid=pid_abc123
보안 주의 : API 키는 비밀번호처럼 취급하세요. 버전 관리에 커밋하거나, 클라이언트 코드에 노출하지 마세요.
반드시 알아둘 핵심 개념
통합에 앞서 아래 핵심 개념을 이해하세요.
Submission 은 단일 신원 인증 시도를 의미합니다. 포함 내용:
Submission ID : 고유 식별자(sub_abc123
)
KYC 상태 : approved
, rejected
, pending
사용자 데이터 : 추출된 정보(이름, 생년, 국적 등)
이미지 : 문서 사진과 셀피
메타데이터 : 타임스탬프, IP, 디바이스 정보
Submission 라이프사이클: Created → Processing → Approved/Rejected/Pending → Archived
웹훅(Webhook) 은 이벤트 발생 시 서버로 실시간 HTTP 콜백을 보내는 기능입니다.
Submission 상태 변경 시 트리거
엔드포인트로 POST 전송
전체 Submission 데이터 포함
재시도 메커니즘 지원
이벤트 유형:
approved
- 검증 승인
rejected
- 검증 거절
pending
- 수동 심사 필요
updated
- 데이터 갱신
deleted
- Submission 삭제
웹훅 페이로드 예시: {
"webhook_trigger" : "approved" ,
"submissionId" : "sub_abc123" ,
"kycStatus" : "approved" ,
"email" : "user@example.com" ,
"fullName" : "John Doe" ,
"birthDate" : "1990-01-01"
}
쿼리 파라미터 로 Liveform 동작을 커스터마이즈:
사용자 데이터 선기입(email
, userid
)
국가/문서 유형 제한
검증 정책 오버라이드
폼 필드 제어
토큰 으로 프라이빗 모드 사용:
1회용 URL
URL 공유 방지
최초 사용 또는 3분 경과 시 만료
프로젝트당 최대 100,000개 토큰
더 알아보기: Query String Guide
ID check는 여러 계층의 암호화를 지원합니다. 1. 쿼리 스트링 암호화 (AES-256-ECB)
민감한 URL 파라미터 암호화
전송 중 사용자 데이터 보호
2. 보안 데이터 전송 (AES-256-ECB/CBC)
API 요청/응답 본문 암호화
웹훅 페이로드 암호화
3. 커스텀 시크릿 키
전용 암호화 키 생성
API 키와 분리하여 관리
더 알아보기: Encryption Guide
파트 2: 통합
이제 여러분의 애플리케이션에 ID check를 통합해봅시다. 통합 방법을 선택하세요:
5단계: 웹훅 설정
웹훅은 검증 이벤트가 발생할 때 실시간 알림을 제공합니다. 이는 운영 배포에 필수적 입니다.
웹훅 엔드포인트 생성
웹훅 POST 요청을 받을 HTTPS 엔드포인트를 생성하세요: Node.js (Express)
Python (Flask)
const express = require ( 'express' );
const app = express ();
app . use ( express . json ());
app . post ( '/webhooks/idcheck' , async ( req , res ) => {
const event = req . body ;
console . log ( '웹훅 수신:' , event . webhook_trigger );
console . log ( '제출 ID:' , event . submissionId );
console . log ( 'KYC 상태:' , event . kycStatus );
try {
// 이벤트 유형에 따라 처리
switch ( event . webhook_trigger ) {
case 'approved' :
await handleApproved ( event );
break ;
case 'rejected' :
await handleRejected ( event );
break ;
case 'pending' :
await handlePending ( event );
break ;
case 'updated' :
await handleUpdated ( event );
break ;
default :
console . log ( '알 수 없는 이벤트 유형:' , event . webhook_trigger );
}
// 항상 빠르게 200 OK 응답
res . status ( 200 ). json ({ received: true });
} catch ( error ) {
console . error ( '웹훅 처리 오류:' , error );
// 처리 오류에도 200을 반환하여 재시도 방지
res . status ( 200 ). json ({ received: true , error: error . message });
}
});
async function handleApproved ( event ) {
// 데이터베이스에서 사용자 업데이트
await db . users . update ({
id: event . userid ,
verified: true ,
verificationDate: new Date (),
fullName: event . fullName ,
birthDate: event . birthDate
});
// 확인 이메일 전송
await sendEmail ( event . email , '검증 승인' , {
name: event . fullName
});
console . log ( `사용자 ${ event . userid } 승인됨` );
}
async function handleRejected ( event ) {
// 사용자 상태 업데이트
await db . users . update ({
id: event . userid ,
verified: false ,
rejectionReason: event . rejectionReason
});
// 사용자에게 알림
await sendEmail ( event . email , '검증 실패' , {
reason: event . rejectionReason
});
console . log ( `사용자 ${ event . userid } 거절됨` );
}
async function handlePending ( event ) {
// 관리자에게 알림
await notifyAdmin ( `사용자 ${ event . userid } 에 대한 수동 심사 필요` );
console . log ( `사용자 ${ event . userid } 심사 대기 중` );
}
async function handleUpdated ( event ) {
// 업데이트된 데이터 동기화
await db . submissions . update ({
submissionId: event . submissionId ,
data: event
});
}
app . listen ( 3000 , () => {
console . log ( '웹훅 서버가 포트 3000에서 실행 중' );
});
중요한 웹훅 모범 사례:
항상 빠르게 200 OK 응답 (5초 이내)
웹훅을 비동기로 처리 (시간이 오래 걸리는 경우)
중복 웹훅 처리 (제출 ID로 중복 제거)
실패한 처리에 대한 재시도 로직 구현
디버깅을 위한 모든 웹훅 로깅
대시보드에서 웹훅 URL 등록
Dashboard 에 로그인
Settings → Access Management 로 이동
웹훅 URL 필드에 웹훅 URL 입력:
https://yourapp.com/webhooks/idcheck
Save 클릭
웹훅 URL은 반드시 HTTPS를 사용 해야 합니다. 로컬 테스트의 경우 ngrok 또는 유사한 도구를 사용하여 로컬 서버를 노출하세요.
웹훅 전송 테스트
옵션 1: webhook.site를 사용한 테스트 1. https://webhook.site 방문
2. 고유 URL 복사
3. 대시보드 웹훅 설정에 입력
4. 테스트 검증 수행
5. webhook.site에서 페이로드 확인
옵션 2: ngrok을 사용한 로컬 테스트 # ngrok 설치
npm install -g ngrok
# 포트 3000에서 로컬 서버 시작
node server.js
# 다른 터미널에서 노출
ngrok http 3000
# HTTPS URL 복사 (예: https://abc123.ngrok.io)
# 대시보드에 https://abc123.ngrok.io/webhooks/idcheck 입력
옵션 3: curl로 테스트 curl -X POST https://yourapp.com/webhooks/idcheck \
-H 'Content-Type: application/json' \
-d '{
"webhook_trigger": "approved",
"submissionId": "test_123",
"kycStatus": "approved",
"email": "test@example.com",
"userid": "test_user"
}'
웹훅 이벤트 처리
사용 가능한 이벤트 유형: 이벤트 트리거 사용 사례 approved
검증 승인 사용자 상태 업데이트, 접근 권한 부여 rejected
검증 거절 사용자 알림, 재제출 요청 pending
수동 심사 필요 관리자 알림, 사용자 안내 updated
데이터 수정 데이터베이스 변경사항 동기화 deleted
제출 삭제 관련 데이터 정리 created
제출 생성 새 검증 추적 retry
사용자 재시도 재시도 패턴 모니터링 injection
API를 통한 데이터 주입 API 작업 로깅 aml
AML 검사 완료 컴플라이언스 결과 처리
웹훅 페이로드 예시: {
"webhook_trigger" : "approved" ,
"submissionId" : "sub_abc123" ,
"kycStatus" : "approved" ,
"email" : "user@example.com" ,
"userid" : "user_12345" ,
"fullName" : "John Doe" ,
"birthDate" : "1990-01-01" ,
"nationality" : "USA" ,
"gender" : "male" ,
"documentType" : "passport" ,
"documentNumber" : "123456789" ,
"issuingCountry" : "USA" ,
"expiryDate" : "2030-01-01" ,
"createdAt" : "2024-01-15T10:30:00Z" ,
"verifiedAt" : "2024-01-15T10:35:00Z" ,
"cf1" : "campaign_summer" ,
"cf2" : null ,
"cf3" : null ,
"ipAddress" : "192.168.1.1"
}
더 알아보기: 웹훅 이벤트 참조
파트 3: 운영 배포
보안 설정
운영 환경으로 전환하기 전에 다음 필수 보안 기능을 구현하세요:
모든 API 요청, 응답, 웹훅을 암호화하세요.
대시보드에서 활성화
Settings → Access Management 로 이동
“Secure Data Transfer” 옵션을 ON 으로 토글
Save 클릭
코드에서 암호화 구현
Node.js - 요청 암호화
Node.js - 응답 복호화
Node.js - 웹훅 복호화 (AES-256-CBC)
const CryptoJS = require ( 'crypto-js' );
function encryptData ( data , apiKey ) {
// API 키를 SHA-256으로 해싱
const hashedKey = CryptoJS . SHA256 ( apiKey );
// AES-256 키를 위해 32바이트 추출
const key = CryptoJS . lib . WordArray . create (
hashedKey . words . slice ( 0 , 8 ),
32
);
// AES-256-ECB로 데이터 암호화
const encrypted = CryptoJS . AES . encrypt (
JSON . stringify ( data ),
key ,
{ mode: CryptoJS . mode . ECB }
);
return encrypted . ciphertext . toString ( CryptoJS . enc . Base64 );
}
// API 요청에서 사용
const userData = {
email: 'user@example.com' ,
fullName: 'John Doe' ,
birthDate: '1990-01-01'
};
const encryptedBody = encryptData ( userData , YOUR_API_KEY );
const response = await axios . post (
'https://rest-api.argosidentity.com/v3/submission/migration' ,
{ body: encryptedBody },
{
headers: {
'x-api-key' : YOUR_API_KEY ,
'Content-Type' : 'application/json'
}
}
);
주요 차이점:
API 요청/응답 : AES-256-ECB 사용
웹훅 : AES-256-CBC 사용
항상 API 키를 SHA-256으로 먼저 해싱
암호화 테스트
구현을 확인하기 위해 암호화/복호화 도구 를 사용하세요:
도구를 다운로드하고 실행
API 키 입력
샘플 데이터로 암호화/복호화 테스트
코드 결과와 비교
도구는 ECB와 CBC 모드를 모두 지원합니다. 둘 다 테스트하세요!
더 알아보기: 암호화 가이드
신뢰할 수 있는 IP 주소에서만 API 접근을 허용하세요.
서버 IP 찾기
# 서버의 공용 IP 찾기
curl ifconfig.me
# 또는 클라우드 제공업체 대시보드에서 확인
# AWS: EC2 Elastic IP
# Google Cloud: External IP
# Azure: Public IP
화이트리스트에 IP 추가
Settings → Access Management → IP Whitelist 로 이동
서버 IP 주소 입력 (한 줄에 하나씩):
Save 클릭
접근 테스트
화이트리스트된 IP에서 (성공해야 함): curl -H "x-api-key: YOUR_API_KEY" \
https://rest-api.argosidentity.com/v3/submission
화이트리스트되지 않은 IP에서 (403으로 실패해야 함): {
"errorCode" : "forbidden" ,
"errorMessage" : "Access denied. IP not whitelisted."
}
API를 호출할 모든 서버 IP를 화이트리스트에 추가해야 합니다:
운영 서버
스테이징 서버
CI/CD 파이프라인 IP (해당하는 경우)
테스트용 관리자/개발자 IP
토큰을 사용하여 안전한 일회용 검증 URL을 생성하세요. 프라이빗 모드 사용 시기:
고보안 애플리케이션 (금융, 의료)
URL 공유/전달 방지
시간 제한이 있는 검증
특정 사용자 세션 추적
구현: // 1. 사용자 세션용 고유 토큰 생성
const tokenId = `session- ${ userId } - ${ Date . now () } ` ;
// 2. ARGOS에 토큰 등록
await fetch ( 'https://rest-api.argosidentity.com/v3/submission/tokens' , {
method: 'POST' ,
headers: {
'x-api-key' : YOUR_API_KEY ,
'Content-Type' : 'text/plain'
},
body: JSON . stringify ({ tokenId: [ tokenId ] })
});
// 3. 안전한 Liveform URL 생성
const secureUrl = `https://form.argosidentity.com?pid= ${ projectId } &token= ${ tokenId } ` ;
// 4. 사용자에게 URL 전송 (이메일, SMS 등)
await sendEmail ( userEmail , {
subject: '신원 인증 완료' ,
body: `인증하려면 여기를 클릭하세요: ${ secureUrl } ` ,
expiresIn: '3분'
});
// 5. 토큰 만료 처리
setTimeout ( async () => {
// 토큰이 사용되었는지 확인
const submission = await getSubmissionByToken ( tokenId );
if ( ! submission ) {
console . log ( `토큰 ${ tokenId } 가 사용되지 않고 만료됨` );
// 선택적으로 사용자에게 알리거나 새 토큰 생성
}
}, 3 * 60 * 1000 ); // 3분
토큰 라이프사이클: 생성됨 → 등록됨 → URL 전송됨 → 사용자가 열음 → 제출 생성됨 → 토큰 소모됨
↓
제출이 최종 상태에 도달하거나 3분 후 만료
더 알아보기: POST Token API
API 키를 클라이언트 코드나 버전 관리에 절대 노출하지 마세요. 모범 사례: 환경 변수
백엔드 프록시 패턴
CI/CD 시크릿 (GitHub Actions)
# .env 파일 (gitignore에 추가!)
ARGOS_API_KEY = argos_live_abc123xyz...
ARGOS_PROJECT_ID = pid_abc123
# Node.js에서 로드
require( 'dotenv' ) .config ();
const apiKey = process.env.ARGOS_API_KEY ;
절대 API 키를 git에 커밋하지 마세요! .gitignore
에 추가:.env
.env.local
.env.production
config/secrets.js
git-secrets 같은 도구를 사용하여 실수로 커밋하는 것을 방지하세요.
남용과 예상치 못한 비용으로부터 통합을 보호하세요. ARGOS 요청 제한:
API 호출: IP당 분당 100개 요청
웹훅 재시도: 지수 백오프로 5회 시도
토큰 등록: 요청당 500개 토큰, 총 100k개
애플리케이션 요청 제한: const rateLimit = require ( 'express-rate-limit' );
// 사용자당 검증 요청 제한
const verificationLimiter = rateLimit ({
windowMs: 60 * 60 * 1000 , // 1시간
max: 3 , // IP당 시간당 최대 3회 검증
message: '검증 시도가 너무 많습니다. 나중에 다시 시도해주세요.' ,
standardHeaders: true ,
legacyHeaders: false ,
});
app . post ( '/api/create-verification' ,
verificationLimiter ,
async ( req , res ) => {
// 검증 로직
}
);
// 데이터베이스에서 사용자별 제한 추적
async function checkUserVerificationLimit ( userId ) {
const recentAttempts = await db . verifications . count ({
userId ,
createdAt: { $gte: new Date ( Date . now () - 24 * 60 * 60 * 1000 ) }
});
if ( recentAttempts >= 5 ) {
throw new Error ( '일일 검증 제한 초과' );
}
}
테스트 체크리스트
운영 환경으로 전환하기 전에 모든 통합 지점을 철저히 테스트하세요:
운영 전환 체크리스트
운영 환경 출시 전 최종 확인사항:
모니터링 설정
다음 항목에 대한 모니터링을 설정하세요: // 예시: 주요 지표 로깅
const metrics = {
verifications_started: 0 ,
verifications_completed: 0 ,
verifications_approved: 0 ,
verifications_rejected: 0 ,
api_errors: 0 ,
webhook_failures: 0 ,
average_completion_time: 0
};
// 애플리케이션에서 추적
function trackVerificationStart () {
metrics . verifications_started ++ ;
// 모니터링 서비스로 전송 (Datadog, New Relic 등)
}
// 웹훅 전송 모니터링
app . post ( '/webhooks/idcheck' , async ( req , res ) => {
const startTime = Date . now ();
try {
await processWebhook ( req . body );
metrics . verifications_completed ++ ;
if ( req . body . kycStatus === 'approved' ) {
metrics . verifications_approved ++ ;
} else if ( req . body . kycStatus === 'rejected' ) {
metrics . verifications_rejected ++ ;
}
} catch ( error ) {
metrics . webhook_failures ++ ;
logger . error ( '웹훅 처리 실패' , { error , body: req . body });
}
const duration = Date . now () - startTime ;
metrics . average_completion_time =
( metrics . average_completion_time + duration ) / 2 ;
res . status ( 200 ). json ({ received: true });
});
모니터링할 주요 지표:
검증 성공률
평균 완료 시간
API 오류율
웹훅 전송률
시스템 가동 시간
데이터베이스 성능
롤아웃 계획
점진적 롤아웃 전략: // 1단계: 사용자의 5% (카나리)
function shouldUseNewVerification ( userId ) {
return parseInt ( userId . slice ( - 2 ), 16 ) % 100 < 5 ;
}
// 2단계: 사용자의 25%
function shouldUseNewVerification ( userId ) {
return parseInt ( userId . slice ( - 2 ), 16 ) % 100 < 25 ;
}
// 3단계: 사용자의 100%
function shouldUseNewVerification ( userId ) {
return true ;
}
// 사용법
if ( shouldUseNewVerification ( user . id )) {
redirectToArgosVerification ( user );
} else {
redirectToOldVerification ( user );
}
고급 기능
AML (자금세탁방지) 스크리닝
전 세계 제재 목록 및 감시 목록에 대한 컴플라이언스 검사를 수행하세요.
대시보드에서 AML 활성화
Settings → General → AML Settings 로 이동
AML 스크리닝 활성화
스크리닝 옵션 구성:
감시 목록 소스 (UN, OFAC, EU 등)
매치 임계값 (퍼지 매칭 민감도)
매치 시 자동 거절
API를 통한 AML 검사 요청
curl -X POST 'https://rest-api.argosidentity.com/v3/submission/aml' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"fullName": "John Doe",
"birthDate": "1990-01-01",
"nationality": "USA",
"submissionId": "sub_abc123"
}'
AML 보고서 조회
curl -X GET 'https://rest-api.argosidentity.com/v3/submission/aml/report?submissionId=sub_abc123' \
-H 'x-api-key: YOUR_API_KEY'
응답: {
"submissionId" : "sub_abc123" ,
"amlStatus" : "clear" ,
"matches" : [],
"checkedAt" : "2024-01-15T10:35:00Z" ,
"sources" : [ "UN" , "OFAC" , "EU" , "UK" ]
}
매치가 발견된 경우: {
"submissionId" : "sub_abc123" ,
"amlStatus" : "match" ,
"matches" : [
{
"name" : "John Doe" ,
"matchScore" : 0.95 ,
"source" : "OFAC" ,
"listType" : "sanctions" ,
"details" : "Sanctioned individual"
}
],
"checkedAt" : "2024-01-15T10:35:00Z"
}
AML 결과 처리
async function handleAMLWebhook ( event ) {
if ( event . webhook_trigger === 'aml' ) {
const { submissionId , amlStatus , matches } = event ;
if ( amlStatus === 'match' ) {
// 심사 대상으로 플래그
await db . submissions . update ({
submissionId ,
flagged: true ,
flagReason: 'AML 매치 감지됨' ,
requiresManualReview: true
});
// 컴플라이언스 팀에 알림
await notifyCompliance ({
type: 'AML_MATCH' ,
submissionId ,
matches
});
// 자동 거절이 활성화된 경우 검증 거절
if ( config . aml . autoReject ) {
await rejectVerification ( submissionId , 'AML 컴플라이언스 문제' );
}
} else {
// 진행 허용
console . log ( ` ${ submissionId } 에 대해 AML 클리어` );
}
}
}
더 알아보기: AML API 참조
지속적인 AML 모니터링
승인된 사용자를 업데이트된 감시 목록과 지속적으로 모니터링하세요.
// 지속적인 모니터링을 위해 사용자 등록
await fetch ( 'https://rest-api.argosidentity.com/v3/submission/aml/ongoing' , {
method: 'POST' ,
headers: {
'x-api-key' : YOUR_API_KEY ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ({
submissionId: 'sub_abc123' ,
recordId: 'user_12345'
})
});
// 새 매치가 발견되면 웹훅 수신
app . post ( '/webhooks/idcheck' , ( req , res ) => {
if ( req . body . webhook_trigger === 'aml_monitor' ) {
console . log ( '지속적인 AML 매치 감지됨:' , req . body );
// 조치 취하기 (계정 동결, 사용자 알림 등)
}
res . status ( 200 ). send ( 'OK' );
});
더 알아보기: AML 지속적인 모니터링
데이터 프로젝션 (필드 필터링)
수집되고 표시되는 데이터 필드를 제어하세요.
사용 사례:
GDPR 컴플라이언스를 위한 데이터 수집 최소화
다양한 검증 수준 생성 (기본 vs 전체)
특정 문서 유형이나 국가에 맞춤화
API를 통한 프로젝션 생성
curl -X POST 'https://rest-api.argosidentity.com/v3/projection' \
-H 'x-api-key: YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"projectionName": "basic-kyc",
"allowedFields": [
"fullName",
"birthDate",
"nationality"
]
}'
응답: {
"message" : "success" ,
"projectionId" : "proj_123abc"
}
Liveform에서 프로젝션 사용
const config = {
projectionId: "proj_123abc"
};
const encryptedConfig = encryptQueryParams ( config , YOUR_API_KEY );
const liveformUrl = `https://form.argosidentity.com?pid={your_pid}&encrypted= ${ encodeURIComponent ( encryptedConfig ) } ` ;
projectionId
대신 projectionName
을 사용할 수도 있지만, 둘을 함께 사용할 수는 없습니다.
결과
이 프로젝션으로 폼은:
이름, 생년월일, 국적만 수집
다른 필드 (주소, 문서 번호 등) 건너뛰기
API 응답과 웹훅에서 프로젝션된 필드만 반환
더 알아보기: 프로젝션 API
다국어 지원
ID check Liveform은 전 세계 사용자를 위한 다국어를 지원합니다.
사용 가능한 언어:
영어 (en
)
한국어 (ko
)
일본어 (ja
)
스페인어 (es
)
프랑스어 (fr
)
독일어 (de
)
기타…
사용법:
// Liveform URL에 lang 파라미터 추가
const liveformUrl = `https://form.argosidentity.com?pid={your_pid}&lang=ko` ;
// 또는 사용자의 브라우저 언어로 자동 결정
const userLang = navigator . language . split ( '-' )[ 0 ]; // 'en', 'ko', 'ja' 등
const liveformUrl = `https://form.argosidentity.com?pid={your_pid}&lang= ${ userLang } ` ;
더 알아보기: Liveform 언어
문제 해결 가이드
자주 발생하는 문제와 해결 방법:
증상:
웹훅 이벤트가 도착하지 않음
웹훅 엔드포인트가 호출되지 않음
가능한 원인 및 해결책:
웹훅 URL이 HTTPS가 아님
❌ http://yourapp.com/webhook
✅ https://yourapp.com/webhook
엔드포인트가 200이 아닌 상태 반환
서버 로그 확인
엔드포인트가 5초 이내에 200 OK
반환하는지 확인
필요시 웹훅을 비동기로 처리
방화벽이 ARGOS IP 차단
방화벽에서 ARGOS 웹훅 IP를 화이트리스트에 추가
ARGOS 지원팀에 IP 범위 확인 요청
대시보드의 엔드포인트 URL 오타
Settings → Access Management에서 URL 재확인
curl로 엔드포인트 테스트: curl -X POST https://yourapp.com/webhook
디버깅 단계: // 상세한 로깅 추가
app . post ( '/webhooks/idcheck' , ( req , res ) => {
console . log ( '=== 웹훅 수신됨 ===' );
console . log ( '헤더:' , req . headers );
console . log ( '본문:' , req . body );
console . log ( '==================' );
res . status ( 200 ). json ({ received: true });
});
// webhook.site로 테스트
// 1. https://webhook.site 방문
// 2. 고유 URL 복사
// 3. 대시보드에 입력
// 4. 테스트 이벤트 트리거
// 5. webhook.site에서 전송 확인
증상: {
"errorCode" : "forbidden" ,
"errorMessage" : "Access denied"
}
가능한 원인 및 해결책:
잘못되었거나 누락된 API 키
# 헤더 형식 확인
✅ x-api-key: argos_live_abc123...
❌ x-api-key: "argos_live_abc123..." (따옴표 없이! )
❌ Authorization: Bearer argos_live... (잘못된 헤더! )
IP가 화이트리스트되지 않음
서버의 공용 IP 확인: curl ifconfig.me
대시보드의 IP 화이트리스트에 추가
프록시/로드 밸런서 사용 시 프록시 IP 화이트리스트
잘못된 API 키 사용
올바른 프로젝트의 API 키 사용 확인
복사-붙여넣기 오류 확인
필요시 API 키 재생성
디버깅: # 명령줄에서 테스트
curl -v -H "x-api-key: YOUR_API_KEY" \
https://rest-api.argosidentity.com/v3/submission
# 응답 헤더에서 단서 확인
# 찾을 항목: X-Request-Id, X-Error-Code
증상:
“Invalid encrypted data” 오류
복호화된 데이터가 깨진 문자
복호화 시 JSON parse error
가능한 원인 및 해결책:
잘못된 암호화 모드 사용
API 요청/응답: AES-256-ECB 사용
웹훅: AES-256-CBC 사용
쿼리 스트링: AES-256-ECB 사용
API 키를 먼저 해싱하지 않음
❌ const key = apiKey ; // 잘못됨!
✅ const hashedKey = CryptoJS . SHA256 ( apiKey ); // 올바름!
인코딩 문제
// 암호화 출력은 반드시 Base64여야 함
✅ encrypted . ciphertext . toString ( CryptoJS . enc . Base64 )
❌ encrypted . toString () // 잘못된 인코딩!
// 복호화 입력은 반드시 Base64 파싱해야 함
✅ CryptoJS . enc . Base64 . parse ( encryptedData )
❌ encryptedData // 잘못됨!
잘못된 키 추출 (ECB)
✅ CryptoJS . lib . WordArray . create ( hashedKey . words . slice ( 0 , 8 ), 32 )
❌ hashedKey // 잘못됨!
테스트: // 암호화를 확인하기 위해 이 테스트 사용
const testData = { test: "hello" };
const encrypted = encryptData ( testData , YOUR_API_KEY );
const decrypted = decryptData ( encrypted , YOUR_API_KEY );
console . log ( '원본:' , testData );
console . log ( '암호화됨:' , encrypted );
console . log ( '복호화됨:' , decrypted );
if ( JSON . stringify ( testData ) === JSON . stringify ( decrypted )) {
console . log ( '✅ 암호화가 올바르게 작동함!' );
} else {
console . log ( '❌ 암호화 실패!' );
}
암호화 도구 를 사용하여 확인하세요!
증상:
이미지 업로드가 400 또는 413 오류 반환
“Image too large” 오류
“Invalid image format” 오류
가능한 원인 및 해결책:
이미지가 너무 큼 (>10MB)
// 업로드 전 압축
const compressedImage = await compressImage ( originalImage , {
maxWidth: 1920 ,
maxHeight: 1080 ,
quality: 0.8
});
지원되지 않는 파일 형식
✅ 지원됨: JPEG, PNG
❌ 지원되지 않음: GIF, BMP, WebP, HEIC
// HEIC를 JPEG로 변환 (iOS 사진)
import heic2any from 'heic2any' ;
if ( file . type === 'image/heic' ) {
const converted = await heic2any ({
blob: file ,
toType: 'image/jpeg'
});
file = converted ;
}
이미지 품질이 나쁨
최소 해상도 확인: 1280x720
이미지가 흐리지 않은지 확인
모든 문서 가장자리가 보이는지 확인
문서에 반사가 없는지 확인
잘못된 Content-Type 헤더
✅ Content-Type: image/jpeg
❌ Content-Type: application/octet-stream
증상:
“Duplicate user detected” 오류
사용자가 이전에 제출하지 않았는데도 제출할 수 없음
가능한 원인 및 해결책:
중복 방지 활성화됨
대시보드 Settings → Project Settings → Duplicate Prevention 확인
rejectDuplicateUser
가 활성화됨
같은 이름+생년월일+국적의 사용자가 이미 검증됨
승인/거절 기간 제한
대시보드 설정이 X일 내 재제출 방지
쿼리 파라미터로 오버라이드:
?approvePeriod=false&rejectPeriod=false
같은 이메일/userid 재사용
각 사용자에 대해 고유 식별자 사용
테스트 이메일 주소 재사용하지 않기
해결책: // 옵션 1: 특정 사용자에 대해 오버라이드
const liveformUrl = `https://form.argosidentity.com?pid={your_pid}&rejectDuplicateUser=false` ;
// 옵션 2: 이전 제출 삭제
await fetch ( `https://rest-api.argosidentity.com/v3/submission?submissionId= ${ oldSubmissionId } ` , {
method: 'DELETE' ,
headers: { 'x-api-key' : YOUR_API_KEY }
});
// 옵션 3: 다른 userid/email 사용
const uniqueUserid = `user_ ${ userId } _ ${ Date . now () } ` ;
증상: {
"errorCode" : "too_many_requests" ,
"errorMessage" : "Rate limit exceeded"
}
해결책:
지수 백오프로 재시도 구현
async function callAPIWithRetry ( url , options , maxRetries = 3 ) {
for ( let i = 0 ; i < maxRetries ; i ++ ) {
try {
const response = await fetch ( url , options );
if ( response . status === 429 ) {
const retryAfter = response . headers . get ( 'Retry-After' ) || ( 2 ** i );
console . log ( `요청 제한됨. ${ retryAfter } 초 후 재시도...` );
await sleep ( retryAfter * 1000 );
continue ;
}
return response ;
} catch ( error ) {
if ( i === maxRetries - 1 ) throw error ;
await sleep ( 1000 * 2 ** i ); // 1초, 2초, 4초
}
}
}
요청 큐잉 구현
const queue = require ( 'p-queue' ). default ;
const apiQueue = new queue ({
concurrency: 1 ,
interval: 1000 , // 초당 1개 요청
intervalCap: 1
});
async function queuedAPICall ( url , options ) {
return apiQueue . add (() => fetch ( url , options ));
}
API 응답 캐싱
const cache = new Map ();
async function cachedGetSubmission ( submissionId ) {
if ( cache . has ( submissionId )) {
return cache . get ( submissionId );
}
const submission = await getSubmission ( submissionId );
cache . set ( submissionId , submission );
// 5분 후 만료
setTimeout (() => cache . delete ( submissionId ), 5 * 60 * 1000 );
return submission ;
}
증상:
“Token expired” 오류
“Token not found” 오류
“Token already used” 오류
가능한 원인 및 해결책:
토큰 만료됨 (최초 사용 후 3분 경과)
// 새 토큰 생성
const newToken = `session- ${ userId } - ${ Date . now () } ` ;
await fetch ( 'https://rest-api.argosidentity.com/v3/submission/tokens' , {
method: 'POST' ,
headers: { 'x-api-key' : YOUR_API_KEY , 'Content-Type' : 'text/plain' },
body: JSON . stringify ({ tokenId: [ newToken ] })
});
// 사용자에게 새 URL 전송
const newUrl = `https://form.argosidentity.com?pid={your_pid}&token= ${ newToken } ` ;
토큰이 이미 사용됨
각 토큰은 하나의 제출만 생성할 수 있음
각 검증 시도에 대해 새 토큰 생성
토큰 풀 초과 (100k 제한)
오래된 토큰 삭제:
curl -X DELETE 'https://rest-api.argosidentity.com/v3/submission/tokens?startDate=2024-01-01&endDate=2024-01-31' \
-H 'x-api-key: YOUR_API_KEY'
대시보드에서 자동 삭제 활성화
토큰 형식이 무효함
8-64자여야 함
영숫자 + -_.
만 허용
문자나 숫자로 시작/끝나야 함
✅ "user-session-123"
✅ "token_abc.xyz"
❌ "-invalid-" ( 하이픈으로 시작 )
❌ "short" ( 너무 짧음 , 8 자 미만 )
❌ "has space" ( 공백 포함 )
모범 사례 요약
모든 통합에 대해
보안
보안 데이터 전송 암호화 활성화
운영 환경에서 IP 화이트리스트 사용
클라이언트 코드에 API 키 노출 금지
민감한 앱에 프라이빗 모드 사용
API 키 정기적 교체 (분기별)
오류 처리
모든 HTTP 오류 코드 처리 (400, 403, 500 등)
지수 백오프로 재시도 로직 구현
디버깅을 위한 오류 로깅 (민감한 데이터 제외)
사용자 친화적인 오류 메시지 표시
중요한 오류에 대한 대체 플로우 보유
웹훅
항상 빠르게 200 OK 응답 (<5초)
웹훅을 비동기로 처리
멱등성 구현 (중복 제거)
모든 웹훅 이벤트 로깅
웹훅 전송률 모니터링
처리 실패에 대한 재시도 로직 구현
테스트
출시 전 모든 통합 지점 테스트
개발 중 테스트 계정/데이터 사용
오류 시나리오 철저히 테스트
고트래픽 앱에 대한 부하 테스트 수행
운영 환경 전에 스테이징에서 모니터링
성능
적절한 경우 API 응답 캐싱
자체 요청 제한 구현
데이터베이스 쿼리 최적화
정적 자산용 CDN 사용
API 응답 시간 모니터링
컴플라이언스
데이터 수집 최소화 (프로젝션 사용)
데이터 보존 정책 구현
규제 산업에 AML 스크리닝 활성화
검증의 감사 로그 유지
GDPR/CCPA 요구사항 준수
추가 리소스
도움이 필요하신가요? 언제든지 연락주세요:
커뮤니티 개발자 커뮤니티 참여 (지원팀에서 링크 제공)
엔터프라이즈 지원 엔터프라이즈 고객용: 전용 지원 채널 제공
다음 단계는?
구축 시작
이제 필요한 모든 것이 있습니다! 사용 사례에 가장 적합한 통합 방법으로 시작하세요.
커뮤니티 참여
다른 개발자들과 연결하고, 경험을 공유하며, 커뮤니티에서 도움을 받으세요.
업데이트 확인
새 기능과 개선사항에 대한 업데이트를 받기 위해 변경 로그 를 구독하세요.
피드백 제공
여러분의 피드백이 ID check를 더 나은 제품으로 만드는 데 도움이 됩니다!
축하합니다! ID check 온보딩 가이드를 완료했습니다. 이제 애플리케이션에 안전하고 컴플라이언스가 준수되는 신원 인증 기능을 구축할 준비가 되었습니다.
프로 팁 : 구축하면서 이 가이드를 북마크하고 문제 해결 섹션을 참조하세요. 즐거운 코딩 되세요!