captcha.go 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package services
  2. import (
  3. "context"
  4. "strings"
  5. "time"
  6. "github.com/mojocn/base64Captcha"
  7. )
  8. // CaptchaResponse 验证码响应结构体
  9. type CaptchaResponse struct {
  10. CaptchaID string `json:"uuid"`
  11. CaptchaImage string `json:"img"`
  12. }
  13. // GenerateCaptcha 生成验证码,并将结果显式存入Redis
  14. func GenerateCaptcha() (*CaptchaResponse, error) {
  15. // 初始化验证码实例(使用base64Captcha的内存存储临时存ID映射,仅用于生成,实际结果存Redis)
  16. driver := GetCaptchaDriver()
  17. memoryStore := base64Captcha.DefaultMemStore // 临时内存存储(仅生成阶段用)
  18. cp := base64Captcha.NewCaptcha(driver, memoryStore)
  19. // 生成验证码:ID、Base64图片、答案、错误
  20. captchaID, b64Image, answer, err := cp.Generate()
  21. if err != nil {
  22. return nil, err
  23. }
  24. // ------------------------------
  25. // 显式将验证码结果存入Redis(核心步骤)
  26. // ------------------------------
  27. redisKey := CaptchaRedisPrefix + captchaID
  28. ctx := context.Background()
  29. // 存入Redis并设置过期时间
  30. err = RedisClient.Set(ctx, redisKey, answer, CaptchaExpireMin*time.Minute).Err()
  31. if err != nil {
  32. return nil, err
  33. }
  34. return &CaptchaResponse{
  35. CaptchaID: redisKey,
  36. CaptchaImage: b64Image,
  37. }, nil
  38. }
  39. // VerifyCaptcha 验证验证码:从Redis读取结果对比
  40. func VerifyCaptcha(captchaID, userInput string) bool {
  41. if captchaID == "" || userInput == "" {
  42. return false
  43. }
  44. // ------------------------------
  45. // 从Redis读取验证码结果
  46. // ------------------------------
  47. ctx := context.Background()
  48. // 获取结果(验证后立即删除,防止重复使用)
  49. storedAnswer, err := RedisClient.Get(ctx, captchaID).Result()
  50. if err != nil { // Redis中无该键或读取失败
  51. return false
  52. }
  53. // 忽略大小写对比
  54. return strings.ToLower(storedAnswer) == strings.ToLower(userInput)
  55. }