最近公司要求做一个滑块验证码,但是因为项目是孵化阶段,暂时不考虑使用第三方验证,于是只能自己写了,于是各种百度,几乎百度不到。
于是我参考了一下网易易盾的滑块验证码,我发现他的北京图片都是480*240的 于是我找了一堆480*240的背景图
准备了10张背景图
我的思路是这样的,找了一张100*100半透明png图
然后随机取一个坐标把这个半透明图盖在背景图上合成一张验证图
在把透明图盖住的地方截取出来 效果如下
剩下的就移交给前端大佬了
上代码 这里我们需要用到一个库 "
Github.com/disintegration/imaging" 使用 go mod的形式安装
func GetRandInt(max int) int {
num, _ := rand.Int(rand.Reader, big.NewInt(int64(max-1)))
return int(num.Int64())
}
func CreateCode() (string, int, int) {
//生成随机数
nums := tool.GetRandInt(10)
imageId := tool.GetUuid()
f, _ := os.Open("./captcha/bg/" + strconv.Itoa(nums) + ".png")
//获取随机x坐标
imageRandX := tool.GetRandInt(480 - 100)
if imageRandX < 200 {
imageRandX += 200
}
//获取随机y坐标
imageRandY := tool.GetRandInt(240 - 100)
if imageRandY < 100 {
imageRandY += 100
}
//转化为image对象
m, err := png.Decode(f)
if err != nil {
panic(err)
}
//设置截取的最大坐标值和最小坐标值
maxPotion := image.Point{
X: imageRandX,
Y: imageRandY,
}
minPotion := image.Point{
X: imageRandX - 100,
Y: imageRandY - 100,
}
subimg := image.Rectangle{
Max: maxPotion,
Min: minPotion,
}
f, err = os.Create("./captcha/code/" + imageId + "screenshot.jpeg")
defer f.Close()
//截取图像
data := imaging.Crop(m, subimg)
jpeg.Encode(f, data, nil)
//设置遮罩
createCodeImg("./captcha/bg/"+strconv.Itoa(nums)+".png", minPotion, imageId)
return imageId, imageRandX, imageRandY
}
func createCodeImg(path string, minPotion image.Point, imageId string) {
bg, err := os.Open(path)
if err != nil {
panic(err)
}
maskFile, err := os.Open("./captcha/mask.png")
if err != nil {
panic(err)
}
bgimg, err := png.Decode(bg)
maskimg, err := png.Decode(maskFile)
data := imaging.Overlay(bgimg, maskimg, minPotion, 1.0)
f, err := os.Create("./captcha/code/" + imageId + ".jpeg")
defer f.Close()
jpeg.Encode(f, data, nil)
}
可以看到我创建了以后我会返回一个图片的id 图片的截图的x坐标和y坐标 把y坐标传给前端,吧图片id记录到cookie,后端把x坐标存到redis里面 前端根据用户传滑动的操作吧x坐标传给后端 后端取出cookie里面的图片id拿到redis里面对比 这个坐标在误差值范围内则验证通过