Go验证码功能实现详解
目录结构
├── internal
│ ├── controller
│ │ └── captcha
│ │ └── captcha.go
│ ├── logic
│ │ └── captcha
│ │ └── captcha.go
│ └── service
│ └── captcha.go
1. Service层定义 (internal/service/captcha.go)
package service
import (
"context"
"github.com/gogf/gf/v2/frame/g"
)
type ICaptcha interface {
// GenerateCaptcha 生成验证码
GenerateCaptcha(ctx context.Context) (id string, b64s string, err error)
// VerifyCaptcha 验证验证码
VerifyCaptcha(ctx context.Context, id string, code string) bool
}
var localCaptcha ICaptcha
func Captcha() ICaptcha {
if localCaptcha == nil {
panic("implement not found for interface ICaptcha, forgot register?")
}
return localCaptcha
}
func RegisterCaptcha(i ICaptcha) {
localCaptcha = i
}
2. Logic层实现 (internal/logic/captcha/captcha.go)
package captcha
import (
"context"
"github.com/gogf/gf/v2/frame/g"
"github.com/mojocn/base64Captcha"
"gf_new_web/internal/service"
)
type sCaptcha struct {
store base64Captcha.Store
}
func init() {
service.RegisterCaptcha(New())
}
func New() *sCaptcha {
return &sCaptcha{
store: base64Captcha.DefaultMemStore,
}
}
// GenerateCaptcha 生成验证码
func (s *sCaptcha) GenerateCaptcha(ctx context.Context) (id string, b64s string, err error) {
// 配置验证码参数
driver := base64Captcha.NewDriverDigit(
80, // 高度
240, // 宽度
6, // 验证码长度
0.7, // 曲线干扰度
80, // 噪点数量
)
// 创建验证码
c := base64Captcha.NewCaptcha(driver, s.store)
// 获取验证码
id, b64s, err = c.Generate()
return
}
// VerifyCaptcha 验证验证码
func (s *sCaptcha) VerifyCaptcha(ctx context.Context, id string, code string) bool {
return s.store.Verify(id, code, true)
}
3. Controller层实现 (internal/controller/captcha/captcha.go)
package captcha
import (
"context"
"gf_new_web/internal/service"
"github.com/gogf/gf/v2/frame/g"
)
type Controller struct{}
func New() *Controller {
return &Controller{}
}
// Generate 生成验证码
type GenerateReq struct {
g.Meta `path:"/captcha" method:"get" tags:"验证码" summary:"获取验证码"`
}
type GenerateRes struct {
Id string `json:"id"` // 验证码ID
Base64 string `json:"base64"` // Base64编码的图片
}
func (c *Controller) Generate(ctx context.Context, req *GenerateReq) (res *GenerateRes, err error) {
id, base64, err := service.Captcha().GenerateCaptcha(ctx)
if err != nil {
return nil, err
}
res = &GenerateRes{
Id: id,
Base64: base64,
}
return
}
// Verify 验证验证码
type VerifyReq struct {
g.Meta `path:"/captcha/verify" method:"post" tags:"验证码" summary:"验证验证码"`
Id string `json:"id" v:"required#验证码ID不能为空"`
Code string `json:"code" v:"required#验证码不能为空"`
}
type VerifyRes struct {
Valid bool `json:"valid"` // 验证结果
}
func (c *Controller) Verify(ctx context.Context, req *VerifyReq) (res *VerifyRes, err error) {
valid := service.Captcha().VerifyCaptcha(ctx, req.Id, req.Code)
res = &VerifyRes{
Valid: valid,
}
return
}
4. 功能说明
4.1 整体架构
- Service层:定义验证码相关的接口
- Logic层:实现具体的验证码生成和验证逻辑
- Controller层:处理HTTP请求,调用Logic层的方法
4.2 主要功能
-
生成验证码
- 接口路径:
/captcha
- 请求方式:GET
- 返回数据:
- id: 验证码ID
- base64: Base64编码的验证码图片
- 接口路径:
-
验证验证码
- 接口路径:
/captcha/verify
- 请求方式:POST
- 请求参数:
- id: 验证码ID
- code: 用户输入的验证码
- 返回数据:
- valid: 验证结果(true/false)
- 接口路径:
4.3 技术特点
- 使用
base64Captcha
库生成验证码 - 支持自定义验证码参数:
- 图片尺寸
- 验证码长度
- 干扰线程度
- 噪点数量
- 使用内存存储验证码信息
- 支持验证后自动清除验证码
4.4 使用示例
// 获取验证码
async function getCaptcha() {
const response = await fetch('/captcha');
const data = await response.json();
// 显示验证码图片
document.getElementById('captchaImg').src = `data.base64}`;
// 保存验证码ID
document.getElementById('captchaId').value = data.id;
}
// 验证验证码
async function verifyCaptcha() {
const id = document.getElementById('captchaId').value;
const code = document.getElementById('captchaInput').value;
const response = await fetch('/captcha/verify', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ id, code }),
});
const result = await response.json();
if (result.valid) {
alert('验证成功!');
} else {
alert('验证失败!');
}
}
5. 注意事项
-
安全性考虑
- 验证码有效期建议设置为5-10分钟
- 验证失败后应立即失效
- 建议增加防暴力破解机制
-
性能优化
- 可以考虑使用Redis替代内存存储
- 合理设置图片大小和质量
-
用户体验
- 提供刷新验证码功能
- 验证码要清晰易识别
- 考虑添加语音验证码支持
6. 可扩展性
-
验证码类型扩展
- 数字验证码
- 字母验证码
- 算术验证码
- 滑动验证码
-
存储方式扩展
- Redis存储
- 数据库存储
-
验证规则扩展
- 大小写敏感/不敏感
- 超时时间
- 重试次数限制
这个实现提供了一个完整的验证码解决方案,包括:
1. 清晰的三层架构设计
2. 详细的代码实现
3. 完整的功能说明
4. 使用示例
5. 注意事项
6. 扩展建议