base64Captcha 验证码生成库
项目简介
base64Captcha 是一个基于 Go 语言的验证码生成库,能够快速生成 base64 编码的验证码图片。
主要特性
- 支持多种验证码类型(数字、字母、数学公式等)
- 可自定义验证码样式和参数
- 提供内存存储方案
- 简单易用的 API 接口
项目结构
base64Captcha.code-workspace # 工作区配置文件
go.mod # Go模块依赖文件
go.sum # 依赖校验文件
index.html # 前端示例页面
main.go # 服务端实现代码
快速开始
- 安装依赖:
go get github.com/mojocn/base64Captcha
- 运行示例:
go run main.go
- 访问 http://localhost:8080 查看效果
知识点总结
验证码生成原理
- 服务端生成随机字符串作为验证码
- 将验证码转换为图像并添加干扰元素
- 将图像转换为 base64 编码返回给前端
- 同时存储验证码答案用于后续验证
安全注意事项
- 验证码应设置合理的过期时间(建议 60-120 秒)
- 验证码使用后应立即作废
- 避免使用可预测的随机数生成器
- 限制验证码请求频率防止暴力破解
性能优化建议
- 使用内存缓存存储验证码
- 合理设置验证码图片大小
- 避免频繁生成验证码
- 使用轻量级字体文件
Gin 框架使用要点
- 使用
gin.Default()
创建路由引擎 - 通过
LoadHTMLGlob
加载 HTML 模板 - 使用
GET
/POST
方法定义路由 - 中间件模式处理请求逻辑
base64Captcha 库核心功能
- 支持多种验证码驱动(字符串、数学公式等)
- 提供内存存储方案
- 可自定义验证码样式参数
- 自动生成 base64 编码图像
- 支持多种字体文件
- 可配置干扰线和噪点
前端验证流程
- 获取验证码图像并显示
- 用户输入验证码后提交表单
- 服务端验证输入是否正确
- 根据验证结果执行相应操作
- 验证失败时自动刷新验证码
main.go
package main
import (
"image/color"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/mojocn/base64Captcha"
)
// 创建一个Captcha对象
var store = base64Captcha.NewMemoryStore(1024, 120*time.Second)
func main() {
// 创建一个Gin引擎
r := gin.Default()
// 设置HTML模板路径
r.LoadHTMLGlob("./*.html")
// 路由:返回index.html
r.GET("/", func(c *gin.Context) {
c.HTML(http.StatusOK, "index.html", nil)
})
// 路由:获取验证码
r.GET("/captcha", captchaMiddleware())
// 路由:验证验证码
r.POST("/verify", verifyCaptchaMiddleware())
// 启动服务器
r.Run(":8080")
}
// 验证码生成中间件
func captchaMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 优化验证码参数:
// 1. 移除干扰线(0)
// 2. 调整字体颜色为黑色(0,0,0,255)以增强对比度
// 3. 增加字符间距(120)
// 4. 简化字符集,移除容易混淆的字符
driverString := base64Captcha.NewDriverString(
80, // 高度
200, // 宽度
0, // 干扰线数量,设为0移除干扰线
5, // 显示线条的选项
6, // 验证码的字符长度
"abcdefghjkmnpqrstuvwxyz23456789", // 验证码字符的来源字符串,移除容易混淆的字符(i,l,o,0,1)
&color.RGBA{125, 125, 125, 255}, // 字验证码背景颜色设为灰色
nil, //字体存储
[]string{"wqy-microhei.ttc"}, //字体文件列表
)
captcha := base64Captcha.NewCaptcha(driverString, store)
// 生成验证码ID和图像
id, b64s, _, err := captcha.Generate()
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}
// 返回base64编码的验证码图像
c.JSON(http.StatusOK, gin.H{
"captcha_id": id,
"captcha_img": b64s,
})
c.Next()
}
}
// 检验验证码的中间件
func verifyCaptchaMiddleware() gin.HandlerFunc {
return func(c *gin.Context) {
// 获取用户输入的验证码ID和验证码值
id := c.DefaultPostForm("captcha_id", "")
userCaptcha := c.DefaultPostForm("captcha", "")
// 校验验证码
if store.Verify(id, userCaptcha, true) {
c.JSON(http.StatusOK, gin.H{"status": "success", "message": "Captcha passed"})
} else {
c.JSON(http.StatusOK, gin.H{"status": "failure", "message": "Invalid captcha"})
}
c.Next()
}
}
index.html
<!DOCTYPE html>
<html>
<head>
<title>验证码示例</title>
</head>
<body>
<h1>验证码验证</h1>
<img id="captchaImg" src="" alt="验证码" />
<form id="captchaForm">
<input type="text" id="captchaInput" placeholder="输入验证码" />
<input type="hidden" id="captchaId" />
<button type="submit">提交</button>
</form>
<script>
// 获取验证码
fetch("/captcha")
.then((response) => response.json())
.then((data) => {
document.getElementById("captchaImg").src = data.captcha_img;
document.getElementById("captchaId").value = data.captcha_id;
});
// 处理表单提交
document
.getElementById("captchaForm")
.addEventListener("submit", function (e) {
e.preventDefault();
const formData = new FormData();
formData.append(
"captcha_id",
document.getElementById("captchaId").value
);
formData.append(
"captcha",
document.getElementById("captchaInput").value
);
fetch("/verify", {
method: "POST",
body: formData,
})
.then((response) => response.json())
.then((data) => {
alert(data.message);
if (data.status === "success") {
// 验证成功后的操作
} else {
// 验证失败,刷新验证码
fetch("/captcha")
.then((response) => response.json())
.then((data) => {
document.getElementById("captchaImg").src =
data.captcha_img;
document.getElementById("captchaId").value =
data.captcha_id;
});
}
});
});
</script>
</body>
</html>