Go 使用Base64Captcha生成数字字母验证码实现安全校验

Base64Captcha可以在服务端生成验证码,以base64的格式返回

安装

复制代码
go get -u github.com/mojocn/base64Captcha
go get -u github.com/gin-gonic/gin

项目结构

代码

Go 复制代码
package captcha_util

import (
	"github.com/mojocn/base64Captcha"
)

// StringCaptcha 验证码工具类
type StringCaptcha struct {
	captcha *base64Captcha.Captcha
}

// NewCaptcha 创建验证码
func NewCaptcha() *StringCaptcha {
	// store
	store := base64Captcha.DefaultMemStore

	// 包含数字和字母的字符集
	source := "123456789abcdefghjkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ"

	// driver
	driver := base64Captcha.NewDriverString(
		80,                           // 高度
		240,                          // 宽度
		6,                            // 噪声点的数量,噪声点可以增加验证码的复杂度,使自动化工具更难识别
		1,                            // 参数控制是否显示干扰线。1表示显示干扰线
		4,                            // 验证码中字符的数量
		source,                       // 用于定义验证码中使用的字符集。source变量需要在代码中定义,并包含所有可能用于生成验证码的字符。
		nil,                          // bgColor *color.RGBA,nil值表示不设置自定义背景颜色,将使用默认的背景颜色
		nil,                          // fontsStorage FontsStorage,nil值表示不使用自定义字体存储(FontsStorage),将使用库的默认字体
		[]string{"wqy-microhei.ttc"}, // 选择字体,确保字体支持所需大小写,nil值表示不指定自定义字体列表,将使用库的默认字体列表
	)

	captcha := base64Captcha.NewCaptcha(driver, store)
	return &StringCaptcha{
		captcha: captcha,
	}
}

// Generate 生成验证码
func (stringCaptcha *StringCaptcha) Generate() (string, string, string) {
	id, b64s, answer, _ := stringCaptcha.captcha.Generate()
	return id, b64s, answer
}

// Verify 验证验证码
func (stringCaptcha *StringCaptcha) Verify(id string, answer string) bool {
	return stringCaptcha.captcha.Verify(id, answer, true)
}
Go 复制代码
package main

import (
	"fmt"
	"gin-mall/captcha_util"
	"github.com/gin-gonic/gin"
	"html/template"
	"net/http"
)

func main() {
	app := gin.Default()

	// 加载模板文件
	app.LoadHTMLGlob("templates/*")

	// 验证码
	stringCaptcha := captcha_util.NewCaptcha()

	// 生成验证码
	app.GET("/generate", func(ctx *gin.Context) {
		id, b64s, answer := stringCaptcha.Generate()
		fmt.Println(answer)

		ctx.HTML(http.StatusOK, "index.html", gin.H{
			"captchaId": id,
			"b64s":      template.URL(b64s),
			"answer":    answer,
		})
	})

	// 刷新验证码
	app.GET("/refresh-captcha", func(ctx *gin.Context) {
		id, b64s, answer := stringCaptcha.Generate()
		ctx.JSON(http.StatusOK, gin.H{
			"captchaId": id,
			"b64s":      template.URL(b64s),
			"answer":    answer,
		})
	})

	// 验证
	app.POST("/verify", func(ctx *gin.Context) {
		answer := ctx.PostForm("answer")
		captchaId := ctx.PostForm("captchaId")

		result := stringCaptcha.Verify(captchaId, answer)

		ctx.JSON(http.StatusOK, gin.H{
			"captchaId": captchaId,
			"answer":    answer,
			"result":    result,
		})
	})

	// 监听并在 http://127.0.0.1:8080 上启动服务
	app.Run()
}
html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Demo</title>
    <!-- 添加内联JavaScript用于刷新验证码 -->
    <script>
        function refreshCaptcha() {
            // 这里需要替换为实际从服务器获取新验证码的逻辑
            // 假设有一个API endpoint比如 /refresh-captcha 可以用来获取新的验证码
            fetch('/refresh-captcha')
                .then(response => response.json())
                .then(data => {
                    // 使用返回的新Base64字符串更新img的src属性
                    document.getElementById('captchaImage').src = data.b64s;
                    // 如果返回的JSON数据中包含新的captchaId,也一并更新
                    if (data.captchaId) {
                        document.querySelector('input[name="captchaId"]').value = data.captchaId;
                    }
                    // 如果返回的JSON数据中包含新的answer,也一并更新
                    if (data.answer) {
                        document.querySelector('input[name="answer"]').value = data.answer;
                    }
                })
                .catch(error => console.error('Error refreshing captcha:', error));
        }
    </script>
</head>
<body>
<!-- 为img标签添加id以便于JavaScript中引用 -->
<img id="captchaImage" src="{{.b64s}}">

<form action="/verify" method="post">
    <input type="text" name="captchaId" value="{{.captchaId}}" hidden>
    <input type="text" name="answer" value="{{.answer}}">

    <input type="submit" value="Submit">
    <!-- 添加刷新验证码的button -->
    <button type="button" onclick="refreshCaptcha()">Refresh Captcha</button>
</form>
</body>
</html>

请求:http://localhost:8080/generate

相关推荐
404.Not Found9 分钟前
Day46 Python打卡训练营
开发语言·python
love530love11 分钟前
【PyCharm必会基础】正确移除解释器及虚拟环境(以 Poetry 为例 )
开发语言·ide·windows·笔记·python·pycharm
凌辰揽月13 分钟前
Web后端基础(基础知识)
java·开发语言·前端·数据库·学习·算法
海奥华216 分钟前
go中的接口返回设计思想
开发语言·后端·golang
lifallen18 分钟前
深入浅出 Arrays.sort(DualPivotQuicksort):如何结合快排、归并、堆排序和插入排序
java·开发语言·数据结构·算法·排序算法
运维开发王义杰18 分钟前
Python: 告别 ModuleNotFoundError, 解决 pipx 环境下 sshuttle 缺少 pydivert 依赖的终极指南
开发语言·python
k要开心20 分钟前
从C到C++语法过度1
开发语言·c++
小吕学编程23 分钟前
策略模式实战:Spring中动态选择商品处理策略的实现
java·开发语言·设计模式
q5673152343 分钟前
IBM官网新闻爬虫代码示例
开发语言·分布式·爬虫
笨笨马甲1 小时前
附加模块--Qt OpenGL模块功能及架构
开发语言·qt