前言
验证码是一个除了限流外很有效的针对恶意爬虫的办法,很不巧在最最近频繁遭到暴力破解,忍无可忍使用了验证码来防止刷接口。
这是一个go的图片验证码库,使用方法也很简单。
使用
安装命令
go get -u github.com/mojocn/base64Captcha
然后使用的话,先开辟一个验证码使用的存储空间
var store = base64Captcha.DefaultMemStore
// base64Captcha.DefaultMemStore是默认的:10240 个 过期时间10分钟
// 也可以自己设定参数base64Captcha.NewMemoryStore(GCLimitNumber, Expiration)
创建验证码驱动
分为5种不同类型的图形验证码
- dight 数字验证码
- audio 语音验证码
- string 字符验证码
- math 数学验证码(加减乘除)
- chinese中文验证码-有bug
// 生成默认数字的driver
driver := base64Captcha.DefaultDriverDigit
// 也可以自定义参数
base64Captcha.NewDriverDigit(height , width , length , maxSkew , dotCount)
// 例子:
driver := base64Captcha.NewDriverDigit(80, 240, 6, 0.7, 80)
生成验证码,同时保存至store
c := base64Captcha.NewCaptcha(driver, store)
// 生成base64图像验证及id
id, b64s, err := c.Generate()
Store Interface
多台服务器需要共享验证码存储,一般为了效率也首选redis,指定存储store需要实现这个接口。
// Store An object implementing Store interface can be registered with SetCustomStore
// function to handle storage and retrieval of captcha ids and solutions for
// them, replacing the default memory store.
//
// It is the responsibility of an object to delete expired and used captchas
// when necessary (for example, the default memory store collects them in Set
// method after the certain amount of captchas has been stored.)
type Store interface {
// Set sets the digits for the captcha id.
Set(id string, value string)
// Get returns stored digits for the captcha id. Clear indicates
// whether the captcha must be deleted from the store.
Get(id string, clear bool) string
//Verify captcha's answer directly
Verify(id, answer string, clear bool) bool
}
实现三个方法即可
func NewDefaultRedisStore() *RedisStore {
return &RedisStore{
Expiration: time.Second * 180,
PreKey: "SALMON_CAPTCHA_",
}
}
type RedisStore struct {
Expiration time.Duration
PreKey string
Context context.Context
}
func (rs *RedisStore) UseWithCtx(ctx context.Context) base64Captcha.Store {
rs.Context = ctx
return rs
}
// 实现store接口
func (rs *RedisStore) Set(id string, value string) error {
err := db.RedisClient.Set(rs.Context, rs.PreKey+id, value, rs.Expiration).Err()
if err != nil {
fmt.Println(err)
}
return nil
}
func (rs *RedisStore) Get(key string, clear bool) string {
val, err := db.RedisClient.Get(rs.Context, key).Result()
if err != nil {
return ""
}
if clear {
err := db.RedisClient.Del(rs.Context, key).Err()
if err != nil {
return ""
}
}
return val
}
func (rs *RedisStore) Verify(id, answer string, clear bool) bool {
key := rs.PreKey + id
v := rs.Get(key, clear)
return v == answer
}
验证验证码
type CaptCha struct {
Captcha string `json:"captcha"` // 验证码
CaptchaId string `json:"captchaId"` // 验证码ID
}
var data CaptCha
data.Captcha = "xxx"
data.CaptchaId = "xxx"
if store.Verify(data.CaptchaId, data.Captcha, true){
fmt.Println("验证码正确")
}else{
fmt.Println("验证码错误")
}
注意:在上面自定义了RedisStore
,将其增加了一个前缀存到了redis中,这也是为了和其他用到redis的地方区分开,但是不重要,在验证时无需加入前缀。 正常使用即可。
- Post link: https://www.godhearing.cn/go-tu-pian-yan-zheng-ma-ku/
- Copyright Notice: All articles in this blog are licensed under unless otherwise stated.