서버 측 연동
위젯은 브라우저에 일회용 토큰을 건넵니다. 그 토큰은 당신의 서버가 Caputchin으로 확인하기 전까지 아무것도 증명하지 않습니다. 이것이 보이는 챌린지를 진짜 보호로 바꾸는 단계이며, 단 한 번의 HTTPS 호출입니다.
당신에게는 아웃바운드 요청을 할 수 있는 백엔드와, 거기서 쓸 수 있는 사이트 키의 시크릿(cpt_sec_...)이 필요하며, 절대 브라우저에는 두지 않습니다.
1. 토큰 읽기
폼이 POST하면, 당신의 핸들러는 당신 자신의 필드 옆에 추가 필드 하나를 받습니다: caputchin-token. 위젯이 방문자가 챌린지를 풀었을 때 그것을 폼에 넣었습니다.
2. /siteverify로 확인하기
토큰과 당신의 시크릿을 POST하세요. 요청과 응답은 reCAPTCHA의 siteverify와 같은 모양이라, 기존 연동을 거의 손대지 않고 옮길 수 있습니다:
POST https://verify.caputchin.com/v1/siteverify
Content-Type: application/json
{ "secret": "cpt_sec_...", "response": "<caputchin-token>" }// Node 18+
const verdict = await fetch("https://verify.caputchin.com/v1/siteverify", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
secret: process.env.CAPUTCHIN_SECRET,
response: token,
}),
}).then((r) => r.json());
if (!verdict.success) {
// reject the submission
}다른 언어로 된 같은 호출은 백엔드 연동 예제에 있습니다.
3. 응답 읽기
{
"success": true,
"error-codes": [],
"platform": { "game_id": "caputchin/games/leaf-memory", "score": 847, "duration_ms": 4200 }
}- **
success**가 분기할 유일한 대상입니다.true는 진짜 방문자가 챌린지를 풀었다는 뜻이니, 요청을 신뢰하세요.false는 버리라는 뜻입니다. - **
error-codes**는success가false일 때 나타나, 무엇이 잘못됐는지(없거나, 만료됐거나, 이미 사용된 토큰 등) 이름을 댑니다. - **
platform**은 클라이언트가 주장한 메타데이터입니다(어떤 게임인지, 점수, 소요 시간). 이것은 nullable이며 보안 신호가 아닙니다. 원하면 분석용으로 기록하되, 절대 점수에 신뢰를 걸지 마세요.
당신을 보호하는 규칙
- 일회용. 토큰은 한 번 검증합니다. 같은 것을 다시 제출하면
success: false가 돌아오니, 리플레이를 직접 추적할 필요가 없습니다. - 짧은 수명. 토큰은 발급 후 10분이 지나면 만료되니, 지연 작업이 아니라 제출을 처리하는 동안 검증하세요.
- 시크릿은 서버에 머뭅니다. 그것은 절대 브라우저로 가지 않으며, 호출을 인증하는 것이 바로 그것입니다.
흔한 실수
- 클라이언트 측에서 검증하기.
pass이벤트와 토큰의 존재는 UX일 뿐입니다. 모든 신뢰 결정은 여기, 서버 측에서, 당신의 시크릿으로 일어납니다. score에 게이트 걸기. 그것은 신뢰 값이 아니라 메타데이터입니다.
자주 묻는 질문
토큰은 얼마나 유효한가요?
발급 후 10분입니다. 제출을 처리하는 동안 검증하세요, 지연 작업이나 나중에 돌 수도 있는 큐에서가 아니라.
같은 토큰을 두 번 검증할 수 있나요?
아니요. 토큰은 일회용입니다. 같은 것을 다시 제출하면 success: false가 돌아오니, 리플레이를 직접 추적할 필요가 없습니다.
score나 game_id를 신뢰해야 하나요?
아니요. platform 블록(게임, 점수, 소요 시간)은 클라이언트가 주장한 메타데이터이며 nullable입니다. 오직 success로만 분기하고, 절대 점수에 신뢰를 걸지 마세요.
이걸 하려면 SDK가 필요한가요?
아니요. 확인은 /v1/siteverify로 보내는 한 번의 HTTPS POST입니다. Node, Python, PHP, Go, Ruby, .NET, curl에서의 같은 호출은 백엔드 연동 예제에 있습니다.