golang生成base64格式的图形验证码

依赖的包
go get -u github.com/mojocn/base64Captcha

文档地址
https://mojotv.cn/go/refactor-base64-captcha

DEMO展示地址,按F12查看参数及返回信息
https://captcha.mojotv.cn/

刚开始运行的时候出现报错

invalid memory address or nil pointer dereference goroutine

the 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 captcha

import (
	"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 captcha

import (
	"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("验证码校验失败")
}
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值