verifycode.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package verifycode
  2. import (
  3. "fmt"
  4. "strings"
  5. "sync"
  6. "github.com/runningwater/gohub/pkg/app"
  7. "github.com/runningwater/gohub/pkg/config"
  8. "github.com/runningwater/gohub/pkg/helpers"
  9. "github.com/runningwater/gohub/pkg/logger"
  10. "github.com/runningwater/gohub/pkg/mail"
  11. // "github.com/runningwater/gohub/pkg/sms"
  12. )
  13. type VerifyCode struct {
  14. Store Store
  15. }
  16. var once sync.Once
  17. var internalVerifyCode *VerifyCode
  18. func NewVerifyCode() *VerifyCode {
  19. once.Do(func() {
  20. internalVerifyCode = &VerifyCode{
  21. Store: NewRedisStore(),
  22. }
  23. })
  24. return internalVerifyCode
  25. }
  26. // SendSMS 发送验证码
  27. // 发送验证码到手机, 调用示例
  28. //
  29. // verifycode.NewVerifyCode().SendSMS(request.Phone)
  30. func (v *VerifyCode) SendSMS(phone string) bool {
  31. // 生成验证码
  32. code := v.generateVerifyCode(phone)
  33. // 方便本地和 测试环境调试
  34. if !app.IsProduction() &&
  35. strings.HasPrefix(phone, config.GetString("verifycode.debug_phone_prefix")) {
  36. // 测试环境,直接返回成功
  37. return true
  38. }
  39. logger.DebugJSON("验证码", "发送验证码", map[string]string{phone: code})
  40. return true
  41. // 发送验证码
  42. // return sms.NewSMS().Send(phone, sms.Message{
  43. // Template: config.GetString("sms.aliyun.template_code"),
  44. // Data: map[string]string{"code": code},
  45. // })
  46. }
  47. // SendEmail 发送验证码
  48. // 发送验证码到邮箱, 调用示例
  49. //
  50. // verifycode.NewVerifyCode().SendEmail(request.Email)
  51. func (v *VerifyCode) SendEmail(email string) error {
  52. // 生成验证码
  53. code := v.generateVerifyCode(email)
  54. // 方便本地和 测试环境调试
  55. if !app.IsProduction() &&
  56. strings.HasSuffix(email, config.GetString("verifycode.debug_email_suffix")) {
  57. return nil
  58. }
  59. content := fmt.Sprintf("<p>您的验证码是:%v</p>", code)
  60. // 发送邮件
  61. mail.NewMailer().Send(mail.Email{
  62. From: mail.From{
  63. Address: config.GetString("mail.from.address"),
  64. Name: config.GetString("mail.from.name"),
  65. },
  66. To: []string{email},
  67. Subject: "Email 验证码",
  68. HTML: []byte(content),
  69. })
  70. return nil
  71. }
  72. // CheckAnswer 检查验证码是否正确
  73. // key: 手机号 或 Email
  74. func (v *VerifyCode) CheckAnswer(key, answer string) bool {
  75. logger.DebugJSON("验证码", "检查验证码是否正确", map[string]string{key: answer})
  76. // 方便本地和 测试环境调试
  77. if !app.IsProduction() &&
  78. (strings.HasPrefix(key, config.GetString("verifycode.debug_phone_prefix")) || strings.HasPrefix(key, config.GetString("verifycode.debug_email_prefix"))) {
  79. return true
  80. }
  81. return v.Store.Verify(key, answer, false)
  82. }
  83. // 生成验证码, 并放置于 Redis 中
  84. func (v *VerifyCode) generateVerifyCode(key string) string {
  85. // 生成随机码
  86. code := helpers.RandomNumber(config.GetInt("verifycode.code_length"))
  87. if app.IsLocal() {
  88. code = config.GetString("verifycode.debug_code")
  89. }
  90. logger.DebugJSON("验证码", "生成验证码", map[string]string{key: code})
  91. // 存储验证码到 Redis
  92. v.Store.Set(key, code)
  93. return code
  94. }