// Package captcha 处理图片验证码逻辑,支持: 1. 生成图片验证码 2. 校验图片验证码 // 支持的存储:redis, memory package captcha import ( "sync" "github.com/mojocn/base64Captcha" "github.com/runningwater/gohub/pkg/app" "github.com/runningwater/gohub/pkg/config" "github.com/runningwater/gohub/pkg/redis" ) type Captcha struct { base64Captcha *base64Captcha.Captcha } // 确保 internalCaptcha 只初始化一次 // 通过 sync.Once 确保线程安全 var one sync.Once var internalCaptcha *Captcha // NewCaptcha 创建一个新的验证码实例 func NewCaptcha() *Captcha { one.Do(func() { // 初始化 Captcha 实例 internalCaptcha = &Captcha{} // 使用 redis 作为存储引擎,并设置 key 的前缀 store := RedisStore{ RedisClient: redis.Redis, KeyPrefix: config.GetString("app.name") + ":captcha:", } // 配置 base64Captcha 驱动信息 driver := base64Captcha.NewDriverDigit( config.GetInt("captcha.height"), // 高度 config.GetInt("captcha.width"), // 宽度 config.GetInt("captcha.length"), // 长度 config.GetFloat64("captcha.maxskew"), // 最大倾斜角度 config.GetInt("captcha.dotcount"), // 图片背景里的混淆点数量 ) // 创建 base64Captcha 实例 internalCaptcha.base64Captcha = base64Captcha.NewCaptcha(driver, &store) }) return internalCaptcha } // GenerateCaptcha 生成验证码 func (c *Captcha) GenerateCaptcha() (id, b64s, answer string, err error) { return c.base64Captcha.Generate() } // VerifyCaptcha 校验验证码 func (c *Captcha) VerifyCaptcha(id, answer string) (match bool) { // 方便本地开发调试 if !app.IsProduction() && id == config.GetString("captcha.testing_key") { return true } // 第三个参数是验证后是否删除,我们选择 false // 这样方便用户多次提交,防止表单提交错误需要多次输入图片验证码 return c.base64Captcha.Verify(id, answer, false) }