당신의 사이트에 위젯 추가하기
이전 레슨에서 BananaSeed의 공개 키를 갖고 있습니다. 이제 React 문의 폼에 위젯을 올리고, 진짜 방문자가 그것을 푸는 모습을 대시보드에서 보고, 그런 다음 그것을 진짜 보호로 바꾸는 단 하나의 서버 호출을 더합니다.
끝나면 갖게 되는 것
- 문의 폼에 올라가 브라우저에서 방문자를 검증하는 위젯.
- 그 검증을 보여 주는 대시보드.
- 유효한 토큰 없는 모든 제출을 버리는 Node 백엔드.
1. React 폼에 위젯 추가하기
패키지를 설치하세요. 이것이 <caputchin-widget> 요소(그리고 다음 레슨을 위한 <caputchin-game> 요소)를 등록합니다:
npm install @caputchin/widget앱 진입점(main.jsx 같은 곳)에서 시작할 때 한 번 임포트하세요:
import "@caputchin/widget";이제 BananaSeed의 문의 폼에 위젯을 올리세요. 체크박스가 풀리면 위젯은 폼에 숨겨진 caputchin-token 필드를 더하고, 당신은 그것을 제출 시 당신 자신의 필드처럼 읽습니다. cpt_pub_...을 당신의 공개 키로 바꾸세요:
export function ContactForm() {
async function handleSubmit(e) {
e.preventDefault();
const data = new FormData(e.currentTarget);
await fetch("/api/contact", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
email: data.get("email"),
message: data.get("message"),
token: data.get("caputchin-token"),
}),
});
}
return (
<form onSubmit={handleSubmit}>
<input name="email" type="email" required />
<textarea name="message" required />
<caputchin-widget sitekey="cpt_pub_..." />
<button type="submit">Send</button>
</form>
);
}빌드 단계 없는 순수 HTML 페이지거나 네이티브 모바일 앱인가요? 스크립트 태그 연동(CDN)과 모바일 앱 가이드를 보세요.
2. 검증되는 모습 보기
앱을 띄우고 문의 폼을 여세요. Caputchin 체크박스가 나타나 클릭 한 번 없이 스스로 닫힙니다. 폼을 제출할 필요조차 없습니다. 이것이 이미 진짜 검증이며, Caputchin에 닿았습니다.
3. 대시보드에서 확인하기
대시보드로 돌아가, 팀을 열고 사이트 키 안으로 들어가세요. 그 통계는 깔때기를 보여 줍니다: 세션 시작됨, 브라우저에서 통과, 서버에서 검증됨, 위협 차단됨. 페이지를 새로고침하세요. 세션 시작됨과 브라우저에서 통과가 이제 둘 다 최소 1을 보여 줍니다. 그것이 당신의 방문입니다. 위젯이 로드되었고(시작됨) 챌린지가 브라우저에서 풀렸습니다(브라우저에서 통과), 백엔드는 전혀 없이.
서버에서 검증됨은 아직 0인데, 당신의 서버에서 아직 아무것도 토큰을 확인하지 않았기 때문입니다. 이 간극이 다음 단계입니다.
위젯이 라이브이고, 대시보드는 당신이 백엔드 코드 한 줄을 쓰기도 전에 이미 진짜 검증을 기록하고 있습니다. 🎉
4. 백엔드에서 토큰 검증하기
브라우저에서 통과란 방문자가 챌린지를 풀었다는 뜻이지만, 당신의 서버가 토큰을 확인하기 전까지 폼은 보호되지 않습니다. 봇은 위젯을 완전히 무시하고 당신의 엔드포인트로 곧장 POST할 수 있습니다. 그래서 당신의 백엔드는 요청을 신뢰하기 전에 모든 토큰을 Caputchin으로 확인합니다. 당신의 시크릿(cpt_sec_...)은 환경 변수에 살지 절대 브라우저에 두지 않습니다:
import express from "express";
const app = express();
app.use(express.json());
app.post("/api/contact", async (req, res) => {
const { email, message, token } = req.body;
const verdict = await fetch("https://caputchin.com/api/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) {
return res.status(400).json({ error: "Could not verify you are human." });
}
// Verified. Handle the real message: store it, email it, whatever you do.
res.json({ ok: true });
});
app.listen(3001);이 verdict.success 확인이 핵심입니다. /api/contact로 곧장 POST하는 봇은 토큰을 지니지 않으니 success가 false로 돌아오고, 메시지는 당신이 손대기도 전에 버려집니다.
백엔드가 없나요? 문제없습니다. 호스팅 인증을 켜면 Caputchin이 이 확인을 대신 수행하고 검증된 제출만 웹훅이나 당신의 받은 편지함으로 전달합니다.
5. 서버 확인 검증하기
이제 엔드포인트가 검증하니, 문의 폼을 한 번 더 제출하세요. 사이트 키의 통계로 돌아가 새로고침하세요: 서버에서 검증됨이 이제 시작됨과 브라우저에서 통과 옆에서 함께 최소 1을 보여 줍니다. 깔때기 전체가 브라우저에서 서버까지 덮였습니다.
이 깔때기를 거꾸로 읽으려면(카운터 사이의 간극이 방문자 이탈과 연동 오류에 대해 무엇을 말해 주는지) 통계와 세션을 보세요.
당신의 문의 폼은 이제 진짜로 보호됩니다: 모든 제출이 당신의 서버에서 확인되고, 토큰 없는 봇은 돌려보내집니다. 🎉
방금 일어난 일
| 단계 | 어디서 | 결과 |
|---|---|---|
폼의 <caputchin-widget> | React | 체크박스가 마운트 시 검증하고 일회용 caputchin-token 필드를 더합니다. |
| 페이지 열기 | 브라우저 | 시작됨과 브라우저에서 통과가 올라갑니다, 백엔드 불필요. |
시크릿과 함께 /siteverify | Node에서 Caputchin으로 | success: true는 요청을 통과시키고, 토큰 없음은 폐기를 뜻하며, 서버에서 검증됨이 올라갑니다. |
다음
체크박스가 동작합니다. 이제 재미있는 부분입니다: 백엔드는 바꾸지 않고 그것을 진짜 플레이 가능한 게임으로 교체하세요.
마켓플레이스에서 게임 추가하기로 계속하세요.