UNPKG

@kanadi/core

Version:

Multi-Layer CAPTCHA Framework with customizable validators and challenge bundles

363 lines (270 loc) 9.46 kB
# Kanadi - Multi-Layer CAPTCHA Framework <div align="center"> <img src="images/kanadi.webp" alt="Kanadi Logo" width="400" /> </div> <br /> 여러 검증 레이어를 지원하는 유연하고 확장 가능한 CAPTCHA 프레임워크입니다. 기존 캡차와 달리, Kanadi는 번들에 있는 모든 챌린지를 완료해야 검증이 완료됩니다. > [English](#english) | [한국어](#한국어) --- ## 한국어 ### 주요 기능 - **멀티 레이어 검증**: 여러 validator를 번들로 묶어서 체인 형태로 검증 - **커스텀 Validator**: `@Validator` 데코레이터로 직접 validator 제작 가능 - **내장 Validator**: Proof of Work (PoW), 브라우저 검증 등 기본 제공 - **강력한 Ban 시스템**: IP/CIDR/ASN/Device/User 단위 차단, Redis 캐싱 - **NestJS 통합**: NestJS 애플리케이션과 완벽하게 통합 - **데이터베이스 지원**: Redis와 PostgreSQL을 이용한 세션 관리 - **유연한 아키텍처**: 모듈화된 설계로 쉬운 커스터마이징 ### 설치 ```bash npm install kanadi # 또는 bun add kanadi ``` ### 빠른 시작 #### 1. Gateway 생성 ```typescript import { KanadiGateway, KanadiClient, KanadiContext } from 'kanadi/gateway'; import { PSQLDatabaseConfig, RedisDatabaseConfig } from 'kanadi/database'; import { PowV2Validator } from 'kanadi/validators'; @KanadiGateway({ namespace: "captcha", config: [ PSQLDatabaseConfig.forRoot({ url: "postgres://user:password@localhost:5432/captcha" }), RedisDatabaseConfig.forRoot({ host: "localhost", password: "your-password", port: 6379 }) ], validators: [ PowV2Validator ] }) export class CaptchaGateway { constructor(private readonly client: KanadiClient) {} async handleOnChallengeCreated(context: KanadiContext) { // 챌린지 번들 생성 const bundle = await context.createBundle('my-bundle-id'); // 번들에 middleware 추가 await bundle.add('pow_v2', { difficulty: 5, data: 'challenge-data' }); // 번들 발행 await bundle.publish(); // 챌린지 발급 return await context.challenge({ bundleId: bundle, timeout: 10000 }); } async handleOnChallengeValidated(context: KanadiContext) { return await context.validate(); } } ``` #### 2. AppModule에 등록 ```typescript import { Module } from '@nestjs/common'; import { CaptchaGateway } from './kanadi.gateway'; @Module({ imports: [CaptchaGateway], // 그냥 직접 import하면 됩니다! }) export class AppModule {} ``` > **주의**: `@KanadiGateway` 데코레이터가 자동으로 NestJS Module로 변환하므로, `forRoot()`나 다른 설정 없이 바로 imports에 추가할 수 있습니다. #### 3. 커스텀 Validator 만들기 ```typescript import { Validator, IChallengeValidator, ChallengeContext, ChallengeStep, StepValidationResult, ChallengeResult } from 'kanadi/middleware'; import { Injectable } from '@nestjs/common'; @Injectable() @Validator({ id: 'my_validator', name: '내 커스텀 Validator', priority: 5, required: true, category: 'custom', description: '커스텀 검증 로직' }) export class MyValidator implements IChallengeValidator { generateChallenge(context: ChallengeContext): ChallengeStep { return { solveId: 'unique-solve-id', validatorId: 'my_validator', validatorName: '내 커스텀 Validator', data: { // 클라이언트에게 전달할 챌린지 데이터 }, timeout: 30 }; } async validate( context: ChallengeContext, solveId: string, submittedData: any ): Promise<StepValidationResult> { // 검증 로직 return { solveId, validatorId: 'my_validator', validatorName: '내 커스텀 Validator', result: ChallengeResult.PASS, score: 100, confidence: 0.95, processingTime: 10, evidence: {}, timestamp: new Date() }; } canExecute(context: ChallengeContext): boolean { return true; } calculateDifficulty(context: ChallengeContext): number { return 5; } } ``` ### API 엔드포인트 프레임워크가 자동으로 다음 엔드포인트를 생성합니다: #### POST `/{namespace}/challenge` 새로운 챌린지 세션을 생성합니다. **응답:** ```json { "status": "Challenge created successfully", "sessionId": "session-id", "challenge": { "id": "challenge-id" }, "timeout": 10000 } ``` #### POST `/{namespace}/siteverify` 챌린지 응답을 검증합니다. **요청 본문:** ```json { "sessionId": "session-id", "challengeId": "challenge-id", "response": {} } ``` **응답:** ```json { "status": "success" } ``` ### 아키텍처 #### 핵심 컴포넌트 - **kanadi/validator**: Validator 데코레이터와 인터페이스 - **kanadi/gateway**: Gateway 데코레이터와 클라이언트 관리 - **kanadi/database**: 데이터베이스 설정 (Redis, PostgreSQL) - **kanadi/models**: Redis OM과 Prisma를 위한 데이터 모델 - **kanadi/validators**: 내장 validator들 #### 데이터 흐름 1. 클라이언트가 챌린지 요청 2. Gateway가 지정된 validator들로 번들 생성 3. 각 validator가 챌린지 생성 4. 클라이언트가 모든 챌린지 해결 5. Gateway가 모든 응답 검증 6. 모든 validator를 통과하면 캡차 완료 ### 내장 Validators #### PowV2Validator 계산 작업을 요구하는 Proof of Work validator입니다. ```typescript await bundle.add('pow_v2', { difficulty: 5, // 0-10, 높을수록 어려움 data: 'challenge-data' }); ``` ### Ban 시스템 강력한 차단 시스템으로 악의적인 요청을 효과적으로 차단할 수 있습니다. #### 주요 기능 - **IP/CIDR 차단**: 단일 IP 또는 IP 대역 차단 (`192.168.1.0/24`) - **ASN 차단**: 전체 네트워크 차단 (`AS54115`) - **Device/User 차단**: 디바이스 및 사용자 단위 차단 - **Session 차단**: 세션과 연관된 모든 엔티티 차단 - **Redis 캐싱**: 밀리초 단위 조회 성능 - **자동 만료**: 임시/영구 차단 지원 #### 빠른 시작 ```typescript import { Ban } from 'kanadi/ban'; await Ban.IP('192.168.1.100', { reason: 'Spam attack', durationMinutes: 60 }); await Ban.IP('192.168.1.0/24', { reason: 'Spam network' }); await Ban.ASN('AS54115', { reason: 'Datacenter abuse', durationMinutes: 1440 }); const result = await Ban.Check('ip', '192.168.1.100'); if (result.banned) { console.log('IP is banned:', result.database?.reason); } await Ban.Remove('ip', '192.168.1.100'); const bans = await Ban.List(20); const stats = await Ban.Stats(); ``` #### CLI 도구 Ban 시스템을 쉽게 관리할 수 있는 CLI 도구를 제공합니다: ```bash bun scripts/ban-test.ts ban-ip 192.168.1.0/24 "Spam network" 60 bun scripts/ban-test.ts ban-asn AS54115 "Datacenter abuse" bun scripts/ban-test.ts check ip 192.168.1.100 bun scripts/ban-test.ts list bun scripts/ban-test.ts stats ``` 자세한 내용은 [Ban 시스템 가이드](./docs/ko/ban-system.md)를 참고하세요. ### 데이터베이스 스키마 프레임워크는 Redis(빠른 인메모리 캐싱)와 PostgreSQL(영구 저장소)을 함께 사용합니다. #### Redis 모델 - KanadiContext - KanadiBundleSession - KanadiValidatorSession - KanadiUser - KanadiDevice - KanadiHistory #### PostgreSQL 테이블 - Redis 모델과 동일하며, 적절한 관계 설정 포함 데이터는 주기적으로 Redis에서 PostgreSQL로 동기화됩니다. ### 문서 자세한 사용법은 한국어 문서를 참고하세요: - **[시작하기](./docs/ko/tutorial.md)**: 설치 및 기본 설정 - **[커스텀 Validator 만들기](./docs/ko/creating-validators.md)**: Validator 제작 가이드 - **[Ban 시스템](./docs/ko/ban-system.md)**: 차단 시스템 완벽 가이드 ### 예제 완전한 예제는 `examples/` 디렉토리를 참고하세요: - **kanadi.gateway.ts**: 전체 gateway 구현 - **validators/browser.validator.ts**: 커스텀 브라우저 검증 예제 - **scripts/ban-test.ts**: Ban 시스템 CLI 도구 - **scripts/ban-cron.ts**: 자동 Ban 정리 스크립트 --- ## English A flexible and extensible CAPTCHA framework that supports multiple validation layers. Unlike traditional CAPTCHAs, Kanadi requires completing all challenges in a bundle before verification is complete. ### Features - **Multi-Layer Validation**: Chain multiple validators together in a bundle - **Custom Validators**: Create your own validators with the `@Validator` decorator - **Built-in Validators**: Includes Proof of Work (PoW) and browser validation - **NestJS Integration**: Seamlessly integrates with NestJS applications - **Database Support**: Redis and PostgreSQL support for session management - **Flexible Architecture**: Modular design allows for easy customization ### Installation ```bash npm install kanadi # or bun add kanadi ``` ### Quick Start See the Korean documentation above for detailed examples. ### Examples See the `examples/` directory for complete working examples. --- ## License MIT