package services import ( "context" "strings" "time" "github.com/mojocn/base64Captcha" ) // CaptchaResponse 验证码响应结构体 type CaptchaResponse struct { CaptchaID string `json:"uuid"` CaptchaImage string `json:"img"` } // GenerateCaptcha 生成验证码,并将结果显式存入Redis func GenerateCaptcha() (*CaptchaResponse, error) { // 初始化验证码实例(使用base64Captcha的内存存储临时存ID映射,仅用于生成,实际结果存Redis) driver := GetCaptchaDriver() memoryStore := base64Captcha.DefaultMemStore // 临时内存存储(仅生成阶段用) cp := base64Captcha.NewCaptcha(driver, memoryStore) // 生成验证码:ID、Base64图片、答案、错误 captchaID, b64Image, answer, err := cp.Generate() if err != nil { return nil, err } // ------------------------------ // 显式将验证码结果存入Redis(核心步骤) // ------------------------------ redisKey := CaptchaRedisPrefix + captchaID ctx := context.Background() // 存入Redis并设置过期时间 err = RedisClient.Set(ctx, redisKey, answer, CaptchaExpireMin*time.Minute).Err() if err != nil { return nil, err } return &CaptchaResponse{ CaptchaID: redisKey, CaptchaImage: b64Image, }, nil } // VerifyCaptcha 验证验证码:从Redis读取结果对比 func VerifyCaptcha(captchaID, userInput string) bool { if captchaID == "" || userInput == "" { return false } // ------------------------------ // 从Redis读取验证码结果 // ------------------------------ ctx := context.Background() // 获取结果(验证后立即删除,防止重复使用) storedAnswer, err := RedisClient.Get(ctx, captchaID).Result() if err != nil { // Redis中无该键或读取失败 return false } // 忽略大小写对比 return strings.ToLower(storedAnswer) == strings.ToLower(userInput) }