captcha

package
v0.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 27, 2026 License: MIT Imports: 3 Imported by: 0

README

captcha — 验证码

提供验证码生成、存储与校验的抽象接口,支持数学运算、图片与滑块三种验证码类型,内置防刷限制。

接口概览

// Generator 生成验证码挑战
type Generator interface {
    Generate(ctx context.Context, captchaType CaptchaType) (*CaptchaData, string, error)
}

// Store 管理验证码持久化
type Store interface {
    Save(ctx context.Context, id string, answer string, ttl time.Duration) error
    Get(ctx context.Context, id string) (string, error)
    Delete(ctx context.Context, id string) error
    Exists(ctx context.Context, id string) (bool, error)
}

// Verifier 验证用户答案
type Verifier interface {
    Verify(ctx context.Context, id string, answer string) (bool, error)
}

验证码类型

类型 常量 说明
数学运算 TypeMath 如 "3 + 5 = ?"
图片识别 TypeImage 图片中的字符
滑块 TypeSlider 拖动到指定位置

快速开始

import "github.com/leeforge/framework/captcha"

// 配置
cfg := captcha.Config{
    Enabled: true,
    TTL:     5 * time.Minute,
    // 生成限制:同一 IP 1 分钟内最多生成 10 次
    GenerateLimit:  10,
    GenerateWindow: time.Minute,
    // 验证限制:同一验证码最多尝试 3 次
    MaxAttempts:   3,
    AttemptWindow: 5 * time.Minute,
    Math: captcha.MathConfig{
        Width: 120, Height: 40, NoiseCount: 5,
    },
}

// 生成验证码
captchaData, answer, err := generator.Generate(ctx, captcha.TypeMath)
// captchaData 返回给前端(含 ID + 挑战数据)
// answer 存入 Store

// 保存答案
store.Save(ctx, captchaData.ID, answer, cfg.TTL)

// 验证
ok, err := verifier.Verify(ctx, captchaID, userAnswer)

典型流程

1. 前端请求验证码 → Handler 调用 Generate → 返回 {id, imageBase64}
2. 用户填写 → 提交表单携带 {captchaID, captchaAnswer}
3. Handler 调用 Verify → 通过 → 继续业务逻辑
                       → 失败 → 返回 422 验证码错误

注意事项

  • Store 的实际实现需对接 Redis,推荐使用 cache 模块的 Redis 适配器
  • 验证成功后应立即删除验证码(Store.Delete),防止重放攻击
  • 启用 RateLimiter 防止爬虫批量获取验证码

Documentation

Index

Constants

This section is empty.

Variables

View Source
var (
	ErrCaptchaNotFound   = errors.New("captcha not found")         // 验证码不存在
	ErrCaptchaExpired    = errors.New("captcha expired")           // 验证码已过期
	ErrInvalidAnswer     = errors.New("invalid answer")            // 答案错误
	ErrRateLimitExceeded = errors.New("rate limit exceeded")       // 超过限流
	ErrGenerationFailed  = errors.New("captcha generation failed") // 生成失败
)

错误定义

Functions

This section is empty.

Types

type CaptchaData

type CaptchaData struct {
	ID        string      `json:"id"`
	Type      CaptchaType `json:"type"`
	Content   string      `json:"content"` // Base64 编码的图片或问题
	ExpiresAt time.Time   `json:"expiresAt"`
}

CaptchaData 表示生成的验证码数据

type CaptchaType

type CaptchaType string

CaptchaType 定义验证码类型

const (
	TypeMath   CaptchaType = "math"   // 数学运算
	TypeImage  CaptchaType = "image"  // 图片验证码
	TypeSlider CaptchaType = "slider" // 滑块验证码
)

type Config

type Config struct {
	Enabled bool          `json:"enabled" yaml:"enabled"` // 是否启用
	TTL     time.Duration `json:"ttl" yaml:"ttl"`         // 过期时间

	// 生成限制
	GenerateLimit  int           `json:"generateLimit" yaml:"generateLimit"`   // 时间窗口内的生成次数限制
	GenerateWindow time.Duration `json:"generateWindow" yaml:"generateWindow"` // 生成限流时间窗口

	// 验证限制
	MaxAttempts   int           `json:"maxAttempts" yaml:"maxAttempts"`     // 最大尝试次数
	AttemptWindow time.Duration `json:"attemptWindow" yaml:"attemptWindow"` // 尝试限流时间窗口

	// 类型特定配置
	Math  MathConfig  `json:"math" yaml:"math"`
	Image ImageConfig `json:"image" yaml:"image"`
}

Config 验证码配置

type Generator

type Generator interface {
	// Generate 生成验证码
	// 返回: CaptchaData (返回给客户端), answer (存储用), error
	Generate(ctx context.Context, captchaType CaptchaType) (*CaptchaData, string, error)
}

Generator 创建验证码挑战

type ImageConfig

type ImageConfig struct {
	Width      int `json:"width" yaml:"width"`           // 宽度
	Height     int `json:"height" yaml:"height"`         // 高度
	Length     int `json:"length" yaml:"length"`         // 字符长度
	NoiseCount int `json:"noiseCount" yaml:"noiseCount"` // 噪点数量
}

ImageConfig 图片验证码配置

type MathConfig

type MathConfig struct {
	Width           int `json:"width" yaml:"width"`                     // 宽度
	Height          int `json:"height" yaml:"height"`                   // 高度
	NoiseCount      int `json:"noiseCount" yaml:"noiseCount"`           // 噪点数量
	ShowLineOptions int `json:"showLineOptions" yaml:"showLineOptions"` // 线条选项
}

MathConfig 数学验证码配置

type RateLimiter

type RateLimiter interface {
	// AllowGenerate 检查用户是否可以生成新验证码
	AllowGenerate(ctx context.Context, identifier string) error

	// AllowVerify 检查用户是否可以验证(处理最大尝试次数)
	AllowVerify(ctx context.Context, identifier string) error

	// RecordFailure 记录验证失败
	RecordFailure(ctx context.Context, identifier string) error

	// Reset 清除标识符的限流记录(成功验证后)
	Reset(ctx context.Context, identifier string) error
}

RateLimiter 防止滥用

type Service

type Service interface {
	// Generate 生成验证码
	Generate(ctx context.Context, captchaType CaptchaType, identifier string) (*CaptchaData, error)

	// Verify 验证验证码
	Verify(ctx context.Context, id string, answer string, identifier string) (*VerifyResult, error)
}

Service 编排验证码操作

type Store

type Store interface {
	// Save 保存验证码答案
	Save(ctx context.Context, id string, answer string, ttl time.Duration) error

	// Get 获取验证码答案
	Get(ctx context.Context, id string) (answer string, err error)

	// Delete 删除验证码
	Delete(ctx context.Context, id string) error

	// Exists 检查验证码是否存在
	Exists(ctx context.Context, id string) (bool, error)
}

Store 管理验证码持久化

type VerifyResult

type VerifyResult struct {
	Valid         bool   `json:"valid"`                   // 是否验证通过
	FailureReason string `json:"failureReason,omitempty"` // 失败原因
	AttemptsLeft  int    `json:"attemptsLeft,omitempty"`  // 剩余尝试次数
}

VerifyResult 包含验证结果

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL