이번 포스팅에서는 로고만 봐도 뭘 하는 녀석인지 바로 알 수 있는 구글 reCAPTCHA에 대해서 정리해본다.
웹 사이트를 이용하다 보면 종종 '로봇이 아닙니다' 하는 문구와 함께
신호등을 선택한다거나 문자를 입력하는 절차를 종종 거치게 된다.
이러한 과정은 웹사이트를 공격하는 봇으로 부터 내 웹사이트를 보호하고자 하는 절차인데
해당 과정이 없을 경우 다양한 방식의 피해를 입을 수 있기 때문에 이러한 안전장치는 반드시 필요한데,
구글 reCAPTCHA는 이러한 부분을 도와주는 고마운 녀석이다.
reCAPTCHA v3
현재 (25년 06월 기준) reCAPTCHA는 v2와 v3를 제공하고 있는데
v2의 경우 앞서 예를 들었던 것 처럼, 웹 사이트의 이용자가 특정 버튼을 클릭하거나 요구하는 조건을 선택하는 방식으로
해당 사용자가 봇인지 사람인지에 대해서 판단할 수 있게 해주었다면,
v3의 경우는 웹 사이트의 이용자가 특별히 어떠한 동작을 하지 않아도 된다.
페이지 내에서 사용자의 행동을 분석해 해당 행동에 대한 점수를 매겨
봇인지 아닌지에 대해서 판단하고 점수에 따라 특정 액션을 취할 수 있도록 해준다.
v2와 v3 중에서 현재 내가 구성하고 있는 서비스 페이지에는
v3가 더 적절할 것으로 판단이 되어 v3를 적용하기로 했다.
** 참고 **
해당 포스팅은 Next.js를 기준으로 적용한 내용을 담고 있습니다.
댓글을 통해 질문 할 때, 제 환경과 다른 환경이라면 답변을 드리기 어려울 수 있습니다.
reCAPTCHA 세팅
위의 이미지를 클릭하면 recaptcha를 설정할 수 있는 페이지로 이동하게 된다.
해당 페이지에서 [시작하기]를 통해 보호할 사이트의 도메인을 등록할 수 있고,
[reCAPTCHA 관리]를 통해 내가 연결한 도메인에 다양한 통계를 확인할 수 있다.
시작하기를 통해 도메인을 등록하게 되면 위의 사진처럼 두 개의 Key를 발급 받게 된다.
// .env
NEXT_PUBLIC_SITE_KEY=
NEXT_PUBLIC_SECRET_KEY=
발급받은 키는 환경변수에 이런 식으로 지정해 놓고 사용했다.
만약 next 환경이 아닌 다른 환경이라면 그 프레임워크에 맞는 방식으로 적용해야하고,
꼭 이름을 저렇게 설정할 필요는 없다.
관리 페이지로 가면 [통합] 탭에 내 사이트에 recaptcha를 적용하는 방법이 안내 되어있다.
해당 방식을 활용해서도 적용할 수 있지만, 조금 더 편리하게 적용할 수 있는 라이브러리가 있어서
해당 라이브러리를 이용해서 적용해 보았다.
react-google-recaptcha-v3
React component for google-recaptcha v3. Latest version: 1.11.0, last published: 14 days ago. Start using react-google-recaptcha-v3 in your project by running `npm i react-google-recaptcha-v3`. There are 119 other projects in the npm registry using react-g
www.npmjs.com
npm install react-google-recaptcha-v3
해당 라이브러리를 프로젝트에 설치하면 일단 초기 세팅 까지는 된 거라고 볼 수 있다.
Code Setting
// layout.tsx
<head>
<Script
async
src={`https://www.google.com/recaptcha/enterprise.js?render=${process.env.NEXT_PUBLIC_SITE_KEY}`}
/>
</head>
먼저 layout 파일에 head 부분에 위와 같은 스크립트 코드를 삽입한다.
그 다음에는 활동을 감지할 영역을 지정해 주어야 하는데,
내 페이지 전체에서 활동을 감지하고 싶다면 전체를 감싸주면 되고,
특정 페이지 혹은 특정 영역한 감지하고 싶다면 해당 영역을 감싸주면 된다.
"use client";
import React, { ReactNode } from "react";
import { GoogleReCaptchaProvider } from "react-google-recaptcha-v3";
const GoogleCaptcha = ({ children }: { children: ReactNode }) => {
const recaptchaKey = process.env.NEXT_PUBLIC_SITE_KEY as string;
return <GoogleReCaptchaProvider reCaptchaKey={recaptchaKey}>{children}</GoogleReCaptchaProvider>;
};
export default GoogleCaptcha;
나의 경우는 감싸는 역할을 GoogleCaptcha라는 컴포넌트를 만들어서 관리했는데
특정 페이지에서만 reCAPTCHA가 필요했기에 해당 컴포넌트를 만들고, 특정 페이지를 감싸는 방식으로 구현했다.
일반적으로는 이 다음 과정에서 클라이언트에서 구글 서버에 SITE_KEY와 함께 토큰을 요청하고
발급받은 토큰을 서버에 보내서 서버에서 토큰과 Secret Key를 이용해 검증을 거친 뒤
결과를 클라이언트로 내려주는데 Next.js에서는 이 과정을 한번에 처리할 수 있었다.
// app/api/recaptchaSubmit/route.ts
import { NextResponse } from "next/server";
import axios from "axios";
export async function POST(request: Request) {
try {
const body = await request.json();
const token = body.token;
if (!token) {
return NextResponse.json({ success: false, message: "No token provided" }, { status: 400 });
}
const secret = process.env.NEXT_PUBLIC_SECRET_KEY;
const verifyUrl = `https://www.google.com/recaptcha/api/siteverify`;
const res = await axios.post(
verifyUrl,
new URLSearchParams({
secret: secret!,
response: token,
}),
{
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
}
);
const result = res.data;
if (!result.success) {
return NextResponse.json(
{ success: false, score: result.score, message: "Failed verification" },
{ status: 403 }
);
}
return NextResponse.json({ success: true, score: result.score });
} catch (error) {
return NextResponse.json({ success: false, message: "reCAPTCHA verification error", error }, { status: 500 });
}
}
app 폴더에 api 폴더를 생성하고 그 안에 api 요청과 응답 과정을 세팅해주었다.
이렇게 하면 구글 서버에서 사용자의 행동의 검증 결과를 응답으로 내려주는데,
해당 값을 가지고 여러 액션을 적용할 수 있겠다.
import { useGoogleReCaptcha } from "react-google-recaptcha-v3";
...
const ActionComponent = () => {
...
const { executeRecaptcha } = useGoogleReCaptcha();
...
const checkRecaptcha = async () => {
if (!executeRecaptcha) return;
const token = await executeRecaptcha("join");
const res = await fetch("/api/recaptchaSubmit", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ token }),
});
const data = await res.json();
if (data.success && data.score > 0.5) {
// success function();
} else {
// fail function();
}
};
...
}
나같은 경우 특정 액션을 실행할 때 검증이 되도록 구현했는데
react-google-recaptcha-v3에서 제공하는 hook을 이용해 토큰을 발급받고
해당 토큰을 이용해 사용자의 행동을 검증한 뒤, score를 통해 분기처리 작업을 적용했다.
여기서 score의 값이 1에 가까울 수록 인간이라고 판단하고, 0에 가까울 수록 봇이라고 판단을 한다.
그래서 조금 더 타이트하게 잡고 싶으면 기준을 0.5가 아닌 더 높게 설정하면 되고,
여유있게 잡고 싶으면 0.5보다 아래로 설정하면 되겠다.
위의 영상은 실제 적용에 대한 전반적인 가이드를 보여주고 있는 영상인데,
설치부터 적용까지 잘 되어있어서 글을 통해서도 잘 모르겠다면 영상을 한번 보는 걸 추천한다.
리캡챠 아이콘 안보이게 하기
리캡챠를 적용하면 실제 페이지에 이런 아이콘이 나오게 되는데,
UI를 가리는 형태로 나오게 되는 경우가 있어서 해당 아이콘을 가리는 방법도 있는데 이건 css로 설정할 수 있다
.grecaptcha-badge {
visibility: hidden;
}
이것처럼 hidden을 주면 안보이도록 설정할 수 있다 ㅎㅎ
포스팅 작성에 참고한 감사한 글들
'Stack > Next.js' 카테고리의 다른 글
[Next.js_Library] Amplitude 적용기 (0) | 2024.03.18 |
---|---|
[Saida Lab] Next-auth 적용하기 (3)_build error (1) | 2024.03.17 |
[Saida Lab] Next-auth 적용하기 (2)_callback (1) | 2024.03.16 |
[Saida Lab] Next-auth 적용하기 (1)_app router + kakao Login (0) | 2024.03.15 |