You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.2 KiB
Go
130 lines
3.2 KiB
Go
1 year ago
|
package captcha
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"git.noahlan.cn/noahlan/ntool-biz/core/config"
|
||
|
"git.noahlan.cn/noahlan/ntool/nlog"
|
||
|
"github.com/mojocn/base64Captcha"
|
||
|
"github.com/redis/go-redis/v9"
|
||
|
"image/color"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
type RedisStore struct {
|
||
|
Expiration time.Duration
|
||
|
Prefix string
|
||
|
Context context.Context
|
||
|
Redis redis.Cmdable
|
||
|
}
|
||
|
|
||
|
// NewRedisStore returns a redis store for captcha.
|
||
|
func NewRedisStore(conf config.RedisConf) *RedisStore {
|
||
|
rdb := redis.NewClient(&redis.Options{
|
||
|
Network: conf.Network,
|
||
|
Addr: conf.Addr,
|
||
|
Username: conf.Username,
|
||
|
Password: conf.Password,
|
||
|
DB: conf.DB,
|
||
|
})
|
||
|
|
||
|
return &RedisStore{
|
||
|
Expiration: time.Minute * 5,
|
||
|
Prefix: "CAPTCHA_",
|
||
|
Redis: rdb,
|
||
|
Context: context.Background(),
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// UseWithCtx add context for captcha.
|
||
|
func (r *RedisStore) UseWithCtx(ctx context.Context) base64Captcha.Store {
|
||
|
r.Context = ctx
|
||
|
return r
|
||
|
}
|
||
|
|
||
|
// Set sets the captcha KV to redis.
|
||
|
func (r *RedisStore) Set(id string, value string) error {
|
||
|
_, err := r.Redis.SetEx(r.Context, r.Prefix+id, value, r.Expiration).Result()
|
||
|
if err != nil {
|
||
|
nlog.Errorw("error occurs when captcha key sets to redis", nlog.Field("detail", err))
|
||
|
return err
|
||
|
}
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
// Get gets the captcha KV from redis.
|
||
|
func (r *RedisStore) Get(key string, clear bool) string {
|
||
|
val, err := r.Redis.Get(r.Context, key).Result()
|
||
|
if err != nil {
|
||
|
nlog.Errorw("error occurs when captcha key gets from redis", nlog.Field("detail", err))
|
||
|
return ""
|
||
|
}
|
||
|
if clear {
|
||
|
_, err := r.Redis.Del(r.Context, key).Result()
|
||
|
if err != nil {
|
||
|
nlog.Errorw("error occurs when captcha key deletes from redis", nlog.Field("detail", err))
|
||
|
return ""
|
||
|
}
|
||
|
}
|
||
|
return val
|
||
|
}
|
||
|
|
||
|
// Verify verifies the captcha whether it is correct.
|
||
|
func (r *RedisStore) Verify(id, answer string, clear bool) bool {
|
||
|
key := r.Prefix + id
|
||
|
v := r.Get(key, clear)
|
||
|
return v == answer
|
||
|
}
|
||
|
|
||
|
// MustNewRedisCaptcha returns the captcha using redis, it will panic when error occur
|
||
|
func MustNewRedisCaptcha(c Config, redisConf config.RedisConf) *base64Captcha.Captcha {
|
||
|
driver := NewDriver(c)
|
||
|
store := NewRedisStore(redisConf)
|
||
|
return base64Captcha.NewCaptcha(driver, store)
|
||
|
}
|
||
|
|
||
|
func NewDriver(c Config) base64Captcha.Driver {
|
||
|
var driver base64Captcha.Driver
|
||
|
|
||
|
bgColor := &color.RGBA{
|
||
|
R: 254,
|
||
|
G: 254,
|
||
|
B: 254,
|
||
|
A: 254,
|
||
|
}
|
||
|
|
||
|
fonts := []string{
|
||
|
"3Dumb.ttf",
|
||
|
"ApothecaryFont.ttf",
|
||
|
"Comismsh.ttf",
|
||
|
"DENNEthree-dee.ttf",
|
||
|
"DeborahFancyDress.ttf",
|
||
|
"Flim-Flam.ttf",
|
||
|
"RitaSmith.ttf",
|
||
|
"actionj.ttf",
|
||
|
"chromohv.ttf",
|
||
|
}
|
||
|
|
||
|
switch c.Driver {
|
||
|
case "digit":
|
||
|
driver = base64Captcha.NewDriverDigit(c.ImgHeight, c.ImgWidth,
|
||
|
c.KeyLen, 0.7, 80)
|
||
|
case "string":
|
||
|
driver = base64Captcha.NewDriverString(c.ImgHeight, c.ImgWidth, 0, 0, c.KeyLen,
|
||
|
"qwertyupasdfghjkzxcvbnm23456789",
|
||
|
bgColor, nil, fonts)
|
||
|
case "math":
|
||
|
driver = base64Captcha.NewDriverMath(c.ImgHeight, c.ImgWidth, 0, 0, bgColor,
|
||
|
nil, fonts)
|
||
|
case "chinese":
|
||
|
// TODO 读取中文列表
|
||
|
driver = base64Captcha.NewDriverChinese(c.ImgHeight, c.ImgWidth, 0, 0, c.KeyLen,
|
||
|
"埃里克森等级分类三级独立开发叫我阿胶发凯撒就看来附件为投靠子女的咖啡",
|
||
|
bgColor, nil, fonts)
|
||
|
default:
|
||
|
driver = base64Captcha.NewDriverDigit(c.ImgHeight, c.ImgWidth,
|
||
|
c.KeyLen, 0.7, 80)
|
||
|
}
|
||
|
|
||
|
return driver
|
||
|
}
|