FingerprintJs/botd를 통한 봇 탐지

팀에서 진행한 프로젝트에서는 봇을 통한 부정 사용자를 막기 위한 다양한 방법을 논의한 끝에, FingerprintJs/botd를 채택하게 되었습니다. 이 글에서는 botd를 적용하는 방법과 그 과정에서 얻은 인사이트를 공유하겠습니다.

FingerprintJS/botd 라이브러리를 설치해줍니다. pnpm, yarn도 동일하게 설치할 수 있습니다.

# npm
npm install @fingerprintjs/botd
 
# pnpm
pnpm add @fingerprintjs/botd
 
# yarn
yarn add @fingerprintjs/botd
 

클라이언트단에서의 botd 적용

저는 botd를 Provider 형식으로 감싸서 전역에서 봇을 감지하는 방식으로 구현했습니다. Next.js 14의 App Router 환경에서 쉽게 적용할 수 있으며, usePathname과 useRouter를 이용해 경로 변경 시마다 봇 탐지를 실행할 수 있습니다.

"use client";
 
import { load } from "@fingerprintjs/botd";
import { usePathname, useRouter } from "next/navigation";
import { useEffect } from "react";
 
export function BotProvider({ children }: { children: React.ReactNode }) {
  const pathname = usePathname();
  const router = useRouter();
 
  useEffect(() => {
    async function detectBot() {
      try {
        const botd = await load();
        const result = botd.detect();
 
        if (result.bot) router.replace("/bot-detected");
      } catch (error) {
        console.error("봇 감지 중 오류 발생:", error);
      }
    }
 
    detectBot();
  }, [pathname]);
 
  return <>{children}</>;
}

전역에서 BotProvider 사용

전역에서 감지를 수행하기 위해 RootLayout에서 BotProvider를 감싸서 사용합니다.

import type { Metadata } from "next";
 
import "./globals.scss";
 
import { BotProvider } from "@shared/context";
 
export const metadata: Metadata = {
  title: "타이틀",
  description: "설명",
  icons: {
    icon: "/favicon.svg",
  },
};
 
export default function RootLayout({
  children,
}: Readonly<{
  children: React.ReactNode;
}>) {
  return (
    <html lang="ko">
      <body>
        <BotProvider>
          // 다음처럼 감싸서 전역에서 감지
          <div className="root_container">{children}</div>
        </BotProvider>
      </body>
    </html>
  );
}

정상적인 이용자의 경우 **botd.detect()**의 값을 확인하면 다음처럼 확인할 수 있습니다.

Sellenium을 통한 부정 이용자의 경우 **botd.detect()**의 값을 확인하면 다음처럼 확인할 수 있습니다.

이를 통해 좀 더 안전한 프로젝트를 구성할 수 있게 됩니다.