Files
sundynix-micro-be/common/utils/captcha/captcha.go
T

67 lines
1.4 KiB
Go

package captcha
import (
"context"
"time"
"github.com/mojocn/base64Captcha"
"github.com/redis/go-redis/v9"
)
var store base64Captcha.Store
// InitWithRedis 使用 Redis 存储初始化验证码
func InitWithRedis(rdb *redis.Client) {
store = &redisStore{rdb: rdb, expiration: 5 * time.Minute}
}
// Generate 生成图形验证码
func Generate() (id string, b64s string, err error) {
if store == nil {
store = base64Captcha.DefaultMemStore // fallback
}
driver := base64Captcha.NewDriverDigit(80, 240, 5, 0.7, 80)
captcha := base64Captcha.NewCaptcha(driver, store)
id, b64s, _, err = captcha.Generate()
return
}
// Verify 验证验证码(验证后自动清除)
func Verify(id, answer string) bool {
if store == nil {
return false
}
return store.Verify(id, answer, true)
}
// =============== Redis Store 实现 ===============
const keyPrefix = "captcha:"
type redisStore struct {
rdb *redis.Client
expiration time.Duration
}
func (s *redisStore) Set(id string, value string) error {
return s.rdb.Set(context.Background(), keyPrefix+id, value, s.expiration).Err()
}
func (s *redisStore) Get(id string, clear bool) string {
ctx := context.Background()
key := keyPrefix + id
val, err := s.rdb.Get(ctx, key).Result()
if err != nil {
return ""
}
if clear {
s.rdb.Del(ctx, key)
}
return val
}
func (s *redisStore) Verify(id, answer string, clear bool) bool {
v := s.Get(id, clear)
return v == answer
}