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

相关推荐
用户962377954484 天前
VulnHub DC-3 靶机渗透测试笔记
安全
叶落阁主5 天前
Tailscale 完全指南:从入门到私有 DERP 部署
运维·安全·远程工作
用户962377954487 天前
DVWA 靶场实验报告 (High Level)
安全
数据智能老司机7 天前
用于进攻性网络安全的智能体 AI——在 n8n 中构建你的第一个 AI 工作流
人工智能·安全·agent
数据智能老司机7 天前
用于进攻性网络安全的智能体 AI——智能体 AI 入门
人工智能·安全·agent
用户962377954487 天前
DVWA 靶场实验报告 (Medium Level)
安全
red1giant_star7 天前
S2-067 漏洞复现:Struts2 S2-067 文件上传路径穿越漏洞
安全
用户962377954487 天前
DVWA Weak Session IDs High 的 Cookie dvwaSession 为什么刷新不出来?
安全
cipher9 天前
ERC-4626 通胀攻击:DeFi 金库的"捐款陷阱"
前端·后端·安全
花酒锄作田12 天前
Gin 框架中的规范响应格式设计与实现
golang·gin