本文共 5564 字,大约阅读时间需要 18 分钟。
依赖的包
go get -u github.com/mojocn/base64Captcha文档地址
https://mojotv.cn/go/refactor-base64-captchaDEMO展示地址,按F12查看参数及返回信息
https://captcha.mojotv.cn/刚开始运行的时候出现报错
invalid memory address or nil pointer dereference goroutinethe demo main.go must run with the frontend html file , otherwise there is no HTTP-Request-JSON-Config-Body param being POST to the go server and that makes the golang-captcha config is not fully initialized
其实是参数传递问题,于是参考DEMO网站使用如下参数
采用 body raw 的方式传递json串{ "ShowLineOptions":["4","2","8"],"CaptchaType":"string","Id":"1ENJhuUtbyvCQozSQmE2","VerifyValue":"","DriverAudio":{ "Length":6,"Language":"zh"},"DriverString":{ "Height":60,"Width":245,"ShowLineOptions":14,"NoiseCount":0,"Source":"1234567890","Length":4,"Fonts":["ApothecaryFont.ttf","DeborahFancyDress.ttf","Flim-Flam.ttf","wqy-microhei.ttc"],"BgColor":{ "R":0,"G":0,"B":0,"A":0}},"DriverMath":{ "Height":60,"Width":240,"ShowLineOptions":14,"NoiseCount":0,"Length":6,"Fonts":["wqy-microhei.ttc"],"BgColor":{ "R":0,"G":0,"B":0,"A":0}},"DriverChinese":{ "Height":60,"Width":320,"ShowLineOptions":0,"NoiseCount":0,"Source":"设想,你在,处理,消费者,的音,频输,出音,频可,能无,论什,么都,没有,任何,输出,或者,它可,能是,单声道,立体声,或是,环绕立,体声的,,不想要,的值","Length":2,"Fonts":["wqy-microhei.ttc"],"BgColor":{ "R":125,"G":125,"B":0,"A":118}},"DriverDigit":{ "Height":80,"Width":240,"Length":5,"MaxSkew":0.7,"DotCount":80}}
选择数字验证码 digital
{ "ShowLineOptions":["4","2","8"],"CaptchaType":"digit","Id":"vzFYDhJTKtFYgBQz6Jo4","VerifyValue":"","DriverAudio":{ "Length":6,"Language":"zh"},"DriverString":{ "Height":60,"Width":245,"ShowLineOptions":14,"NoiseCount":0,"Source":"1234567890","Length":4,"Fonts":["ApothecaryFont.ttf","DeborahFancyDress.ttf","Flim-Flam.ttf","wqy-microhei.ttc"],"BgColor":{ "R":0,"G":0,"B":0,"A":0}},"DriverMath":{ "Height":60,"Width":240,"ShowLineOptions":14,"NoiseCount":0,"Length":6,"Fonts":["wqy-microhei.ttc"],"BgColor":{ "R":0,"G":0,"B":0,"A":0}},"DriverChinese":{ "Height":60,"Width":320,"ShowLineOptions":0,"NoiseCount":0,"Source":"设想,你在,处理,消费者,的音,频输,出音,频可,能无,论什,么都,没有,任何,输出,或者,它可,能是,单声道,立体声,或是,环绕立,体声的,,不想要,的值","Length":2,"Fonts":["wqy-microhei.ttc"],"BgColor":{ "R":125,"G":125,"B":0,"A":118}},"DriverDigit":{ "Height":80,"Width":240,"Length":4,"MaxSkew":0.7,"DotCount":80}}
精简后
{ "CaptchaType":"digit","Id":"vzFYDhJTKtFYgBQz6Jo4","VerifyValue":"","DriverDigit":{ "Height":80,"Width":240,"Length":4,"MaxSkew":0.7,"DotCount":80}}
接下来对验证码的使用做一个封装,方便调用。
1、使用redis驱动存储验证码。 2、只使用数组验证码。 3、使用带有用户标识的key代替默认的随机的key来存储验证码。captcha.go 文件
package captchaimport ( "math/rand" "time" "github.com/mojocn/base64Captcha")func init() { rand.Seed(time.Now().UnixNano())}type configJsonBody struct { Id string CaptchaType string VerifyValue string DriverAudio *base64Captcha.DriverAudio DriverString *base64Captcha.DriverString DriverChinese *base64Captcha.DriverChinese DriverMath *base64Captcha.DriverMath DriverDigit *base64Captcha.DriverDigit}var store = RedisStore{ }//var store = base64Captcha.DefaultMemStore// 使用 digit// key 为用户标识,比如手机号,token, openid等func Generate(key string) (id string, b64s string, err error) { //parse request parameters param := configJsonBody{ Id: "", CaptchaType: "digit", VerifyValue: "", DriverDigit: &base64Captcha.DriverDigit{ Height: 80, Width: 240, Length: 4, MaxSkew: 0.7, DotCount: 80, }, } var driver base64Captcha.Driver //create base64 encoding captcha switch param.CaptchaType { case "audio": driver = param.DriverAudio case "string": driver = param.DriverString.ConvertFonts() case "math": driver = param.DriverMath.ConvertFonts() case "chinese": driver = param.DriverChinese.ConvertFonts() default: driver = param.DriverDigit } c := base64Captcha.NewCaptcha(driver, store) // 默认的方式下,id是随机生产的,现在改成定制的id //id, b64s, err := c.Generate() id, content, answer := c.Driver.GenerateIdQuestionAnswer() item, err := c.Driver.DrawCaptcha(content) if err != nil { return "", "", err } // 使用key代替id来存储验证码 c.Store.Set(key, answer) b64s = item.EncodeB64string() return id, b64s, err}func Verify(id string, VerifyValue string) (res bool) { //parse request json body param := configJsonBody{ Id: id, CaptchaType: "digit", VerifyValue: VerifyValue, DriverDigit: &base64Captcha.DriverDigit{ Height: 80, Width: 240, Length: 4, MaxSkew: 0.7, DotCount: 80, }, } //verify the captcha return store.Verify(param.Id, param.VerifyValue, true)}
RedisStore.go 文件
package captchaimport ( "strconv" "voteapi/pkg/gredis")const CAPTCHA = "captcha:"type RedisStore struct { }// 存储的是 "8926" 而不是 8926,需要转换一下func (r RedisStore) Set(id string, value string) { v ,_ := strconv.Atoi(value) gredis.Set(CAPTCHA + id, v, 180)}func (r RedisStore) Get(id string, clear bool) string { key := CAPTCHA + id re, err := gredis.Get(key) if err != nil { return "" } if clear { gredis.Delete(key) } return string(re)}func (r RedisStore) Verify(id, answer string, clear bool) bool { v := RedisStore{ }.Get(id, clear) return v == answer}
调用验证码
func Captcha(c *gin.Context) { key := c.DefaultQuery("key", "") if key == "" { response.JsonResponseError(c, "参数错误") return } id, b64s, err := captcha.Generate(util.Md5(key)) if err != nil { response.JsonResponseError(c, err.Error()) return } body := make(map[string]interface{ }) body["id"] = id body["b64s"] = b64s response.JsonResponseSuccess(c, body)}
校验验证码
if !captcha.Verify(captchaKey, verifyCode) { return votedArr, errors.New("验证码校验失败")}
转载地址:http://bcaui.baihongyu.com/