[CloudFlare 턴스타일 인증]

JAMEe_·2024년 8월 7일

인증

목록 보기
1/2

실시간 소켓 통신을 하는 서버를 구현 중 봇을 막아야할 필요성을 느끼고 CloudeFlare 를 적용

CloudFlare 턴스타일이란?

사용자 경험을 개선하고 보안을 강화하기 위해 설계된 캡차(CAPTCHA) 대체 솔루션
사용자가 직접 문제를 해결하지 않아도 되도록 비침입적 방식으로 인간과 봇을 구별
기존 캡챠 방식은 사용자 경험 및 접근성에 영향을 끼치고, 봇들이 진화하면서 인간보다 더 문제를 잘 맞추게 되었다
이 시점에서 기존 캡챠 방식의 문제들을 완화한 CloudFlare turnstile 이 등장하였다

어떻게 봇인지 구분하는걸까?

사용자가 웹페이지를 로드할 때 브라우저 환경과 행동 패턴, 네트워크 정보, 기기 정보 등을 분석한 정보들을 cloudFlare 에 전송
cloudFlare 의 머신러닝 모델이 받은 데이터들을 기반으로 봇인지 사람인지 판단
의심스러운 경우 추가적인 검증 절차를 거치게함 ( e.g. 사람이라면 체크박스를 체크해주세요. )

사이트에 적용하기

  1. https://www.cloudflare.com/ko-kr/products/turnstile 이동하여 회원가입 진행
  2. 사이트 추가 및 API 키 생성
    사이트 관리 시 필요한 이름을 입력하고, 이 턴스타일을 적용할 도메인을 입력
    ※ 도메인을 아직 등록하지 않았다면 Websites 탭에 Add a site
  3. 프론트엔드 코드에 적용시키기
// index.html
 <script src="https://challenges.cloudflare.com/turnstile/v0/api.js?render=explicit"></script>

// Turnstile.tsx
useEffect(() => {
    window.turnstile.ready(function () {
      window.turnstile.render("#cfsc", {
        // 발급받은 사이트 키
        sitekey: `${import.meta.env.VITE_CF_SITE_KEY}`,
        callback: async (token: any) => {
          const response = await fetch(
            `${import.meta.env.VITE_BACKEND_URL}/check-cf`,
            {
              method: "POST",
              headers: {
                "Content-Type": "application/json",
              },
              body: JSON.stringify({ token }),
            }
          );
          const data = await response.json();
          handleCf(data.status);
        },
      });
    });
  }, []);

return <div id="cfsc" className="mb-2" />;
  1. 백엔드 코드에 적용시키기
app.post("/check-cf", async (req, res) => {
  // 발급받은 시크릿 키
  const secretKey = process.env.CF_SECRET_KEY;
  // 프론트에서 callback으로 넘어온 token
  const { token } = req.body;
  try {
    const response = await axios.post(
      "https://challenges.cloudflare.com/turnstile/v0/siteverify",
      {
        secret: secretKey,
        response: token,
        // "remoteip": "사용자의 IP" // 필요시 추가
      },
      {
        headers: { "Content-Type": "application/json" },
      }
    );

    /* 
    {
     "success": true,
     "challenge_ts": "2022-02-28T15:14:30.096Z",
     "hostname": "example.com",
     "error-codes": [],
     "action": "login",
     "cdata": "sessionid-123456789"
    }
    */
    if (response.data.success) {
      res.json({ status: 200, message: "success" });
    } else {
      res.json({ status: 500, message: "fail" });
    }
  } catch (e) {
    console.error(e);
    res.json({ status: 500, message: "error" });
  }
});
profile
안녕하세요

0개의 댓글