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>