캡차 통합

폼에 캡차 보호를 추가하여 봇과 스팸으로부터 웹사이트를 보호하는 방법을 알아보세요. PrivateStater 캡차는 VPN을 사용하는 고객도 원활하게 사용할 수 있도록 설계되었습니다. (Google reCAPTCHA는 VPN 사용자에게 10번이 넘는 캡차를 요구하는 경우가 많습니다.)

작동 방식

PrivateStater 캡차는 3단계 검증을 사용합니다:

  1. 허니팟 (Honeypot) - 봇과 AI가 자동으로 채우는 숨겨진 필드를 감지합니다.

    주로 AI 봇을 방어하는데 효과적이지만 AI 브라우저를 사용하는 고객도 차단될수도 있으니 필요하지 않은 경우 체크를 해제해 기능을 해제하세요.

  2. 퍼즐 챌린지 - 사용자가 퍼즐 조각을 드래그하여 맞춥니다.
  3. PoW (Proof of Work) - Argon2id 해싱을 수행하여 봇의 공격 비용을 증가시킵니다.

스크립트 설치

만약 이미 스크립트를 설치했다면 이 섹션을 건너뛰세요. 모든 기능은 하나의 통합된 privatestater.js 스크립트로 제공됩니다.

웹사이트의 <head> 섹션에 다음 스크립트를 추가하세요:

<script> window.PrivateStaterConfig = { prstSite: "YOUR_SITE_ID" }; </script>
<script src="https://privatestater.com/privatestater.js"></script>

YOUR_SITE_ID를 대시보드에서 생성한 웹사이트 ID로 교체하세요.

대시보드에서 캡차 활성화

  1. 대시보드 > 캡차 > 설정으로 이동합니다
  2. 캡차 활성화를 켭니다
  3. 필요한 옵션을 설정합니다

설정 옵션

설정 설명 기본값
활성화 캡차 기능 사용 여부 비활성화
로컬호스트 허용 localhost에서 테스트 허용 비활성화
허니팟 활성화 AI/봇 감지용 숨겨진 필드 활성화
PoW 난이도 작업 증명 난이도 (low/medium/high) medium

PoW 난이도별 차이

난이도 반복 횟수 예상 소요 시간
low 16회 ~1초
medium 24회 ~2초
high 32회 ~3초

난이도가 높을수록 봇 차단에 효과적이지만 사용자 대기 시간이 길어집니다.

캡차 위젯 추가

방법 1: 자동 초기화 (권장)

폼 내에 캡차를 표시할 위치에 data-captcha 속성이 있는 div를 추가합니다:

<form id="contact-form">
    <input type="text" name="name" placeholder="이름">
    <input type="email" name="email" placeholder="이메일">

    <!-- 캡차 위젯 -->
    <div data-captcha="prst"></div>

    <button type="submit">제출</button>
</form>

페이지가 로드되면 캡차 위젯이 자동으로 나타납니다.

방법 2: 프로그래밍 방식

JavaScript로 캡차를 동적으로 표시할 수 있습니다:

window.PrivateStater.showCaptcha({
    container: document.getElementById('captcha-container'),
    onSuccess: function(token) {
        console.log('검증 성공. 토큰:', token);
        // 토큰을 서버로 전송
    },
    onError: function(error) {
        console.error('검증 실패:', error);
    }
});

showCaptcha 옵션

옵션 타입 설명
container Element 캡차를 렌더링할 DOM 요소 (선택, 없으면 document.body)
onSuccess Function 검증 성공 시 콜백 (토큰 전달)
onError Function 검증 실패 시 콜백 (에러 메시지 전달)

반환값

showCaptcha는 다음 메서드를 가진 객체를 반환합니다:

const captcha = await window.PrivateStater.showCaptcha({...});

// 위젯 제거
captcha.destroy();

콜백 처리

자동 초기화 방식 (data-captcha)

전역 콜백 함수를 정의합니다:

<script>
    window.onPrivateStaterCaptchaSuccess = function(token) {
        console.log('캡차 검증 성공.');

        // 폼에 토큰 추가
        document.getElementById('captcha-token').value = token;

        // 또는 바로 폼 제출
        document.getElementById('contact-form').submit();
    };

    window.onPrivateStaterCaptchaError = function(error) {
        console.error('캡차 에러:', error);
        alert('캡차 검증에 실패했습니다. 다시 시도해주세요.');
    };
</script>

폼 제출 예시

<form id="contact-form" action="/submit" method="POST">
    <input type="text" name="name" required>
    <input type="email" name="email" required>

    <!-- 캡차 토큰을 저장할 숨겨진 필드 -->
    <input type="hidden" id="captcha-token" name="captchaToken">

    <!-- 캡차 위젯 -->
    <div data-captcha="prst"></div>

    <button type="submit">제출</button>
</form>

<script>
    window.onPrivateStaterCaptchaSuccess = function(token) {
        document.getElementById('captcha-token').value = token;
    };
</script>

서버에서 토큰 검증

클라이언트에서 받은 토큰을 서버에서 검증해야 합니다.

API 요청

const response = await fetch('https://privatestater.com/api/captcha/validate', {
    method: 'POST',
    headers: {
        'Content-Type': 'application/json'
    },
    body: JSON.stringify({
        websiteId: 'YOUR_SITE_ID',
        verifyToken: captchaToken
    })
});

const result = await response.json();
if (result.success) {
    // 캡차 검증 성공, 폼 처리 진행
} else {
    // 검증 실패
    console.error('캡차 검증 실패:', result.error);
}

Node.js/Express 예시

app.post('/submit', async (req, res) => {
    const { name, email, captchaToken } = req.body;

    // 캡차 토큰 검증
    const captchaResponse = await fetch('https://privatestater.com/api/captcha/validate', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({
            websiteId: process.env.PRST_SITE_ID,
            verifyToken: captchaToken
        })
    });

    const captchaResult = await captchaResponse.json();

    if (!captchaResult.success) {
        return res.status(400).json({ error: '캡차 검증 실패' });
    }

    // 캡차 검증 성공, 폼 처리 진행
    // ...

    res.json({ success: true });
});

검증 API 응답

성공 시:

{
    "success": true
}

실패 시:

{
    "success": false,
    "error": "token_invalid_or_expired"
}

주의사항

캡차 통계

대시보드에서 캡차 사용 통계를 확인할 수 있습니다:

통계 설명
시도 캡차 챌린지 생성 횟수
성공 검증 완료 횟수
허니팟 실패 허니팟에 걸린 봇 수
퍼즐 실패 퍼즐 맞추기 실패 횟수
PoW 실패 작업 증명 실패 횟수
시간 초과 5분 내 완료하지 못한 횟수
성공률 성공 / 시도 비율

스타일

캡차 위젯은 Shadow DOM으로 격리되어 있어 외부 CSS의 영향을 받지 않습니다. 위젯은 자동으로 다크 모드와 라이트 모드에 맞게 표시됩니다. (prefers-color-scheme 감지)

다국어 지원

캡차 위젯은 브라우저 언어에 따라 자동으로 한국어 또는 영어로 표시됩니다. 추가로 필요한 언어가 있다면 문의해 주시면 빠르게 추가해 드리겠습니다.

문제 해결

캡차가 표시되지 않아요

  1. 대시보드에서 캡차가 활성화되어 있는지 확인하세요
  2. 스크립트가 올바르게 설치되었는지 확인하세요
  3. 브라우저 콘솔에서 에러를 확인하세요

localhost에서 작동하지 않아요

대시보드에서 로컬호스트 허용 옵션을 활성화하세요.

토큰 검증이 실패해요

에러 코드

에러 원인
token_invalid_or_expired 토큰이 만료되었거나 이미 사용됨
website_id_mismatch 토큰과 websiteId가 일치하지 않음
captcha_not_enabled 캡차가 활성화되어 있지 않음
host_mismatch 요청 Origin이 등록된 도메인과 불일치