《go-zero云笺密钥录》_go-zero base64captcha
目录
编辑
编辑
一、前言
二、正文
1.编写api接口
1.1 fac-contact.api
1.2 fca.api
2. 编写Handler函数
3. 编写Logic函数
3.1 base64Captcha.NewDriverDigit()
3.2 base64Captcha.NewCaptcha ()
3.3 Generate()
3.4 Set()
3.5 具体实现
三、结语
一、前言
本文将为大家带来go-zero框架下如何实现一个能够随机生成随机数字验证码的api接口。
二、正文
1.编写api接口
在go-zero框架下要实现一个接口,我们需要先定义一个api文件,在这个文件中声明我们要实现接口的函数名,参数和返回值,如果参数和返回值是自定义类型的的话,我们还需要将具体的类型定义写在api文件中。笔者将生成随机图形验证码的函数,参数和返回值声明在fac-contact.api中,所有的接口api都聚合在一个总的api文件,即fca.api,后续的话就只需要根据这一个fca.api就可以自主生成所有接口后续的handle和logic文件
1.1 fac-contact.api
@server (prefix: /api/v1timeout: 15s group: contact)service fca-api {@doc(summary: \"获取图形验证码\"description: \"生成并返回图形验证码\")@handler WebsiteCaptchaHandler // TODO: set handler name and delete this commentget /contact/captcha returns(ContactCaptchaResp)}
1.2 fca.api
import \"fca-contact.api\" type ContactCaptchaResp {Data ContactCaptchaRespData `json:\"data,omitempty\"`}type ContactCaptchaRespData {CaptchaId string `json:\"captchaId\"` //与验证码对应的IDImageBase64 string `json:\"imageBase64\"` //生成的图形验证码}
这里的CaptchaId是为了后续将用户输入的图形验证码与ID对应的图形验证码进行比对,如果相等即说明用户输入正确,相反则说明错误
在写完api文件后,我们执行下述代码,go-zero框架就可以自主帮我们生成后面的Handle函数和Logic函
goctl api go -api ./fca.api -dir .
注: goctl(Go Control Tool)是 go-zero 框架的代码生成工具,用于自动化生成项目代码、配置文件及部署脚本,主要功能包括:
● 项目脚手架生成:快速创建 API 服务、RPC 服务等基础代码结构。
● 代码生成:根据定义文件(如 .api、.proto)生成模型层、逻辑层、路由层代码3。
● 配置管理:生成与框架兼容的配置文件(如 yaml 格式)。
● 部署支持:生成 Dockerfile 或 Kubernetes 部署模板。
生成API服务
goctl api go -api user.api -dir .
● user.api 文件定义了接口路径、请求/响应结构等。
● 生成代码包含路由、处理函数及中间件框架
2. 编写Handler函数
在Handler函数这一块,我们主要的思路是在logic函数来写具体的实现,而Handler函数只需要调用logic函数即可
package contactimport (\"net/http\"\"fca/api/internal/logic/contact\"\"fca/api/internal/svc\"\"github.com/zeromicro/go-zero/rest/httpx\")func WebsiteCaptchaHandler(svcCtx *svc.ServiceContext) http.HandlerFunc {return func(w http.ResponseWriter, r *http.Request) {l := contact.NewWebsiteCaptchaLogic(r.Context(), svcCtx)resp, err := l.WebsiteCaptcha()if err != nil {httpx.ErrorCtx(r.Context(), w, err)} else {httpx.OkJsonCtx(r.Context(), w, resp)}}}
3. 编写Logic函数
在Logic函数这一块我们来写具体图像验证码的生成实现,这里我们需要引用库\"github.com/mojocn/base64Captcha\",通过其中的若干函数帮助我们生成一个四位数字的图形验证码还有\"github.com/go-redis/redis/v8\"将我们的生成的答案和id存储到redis里面
3.1 base64Captcha.NewDriverDigit()
func NewDriverDigit(height, width, length int, maxSkew float64, dotCount int) *DriverDigit
base64Captcha.NewDriverDigit() 是 Go 语言库 base64Captcha 中用于生成数字类型验证码驱动的构造函数,其核心功能是配置验证码的样式和复杂度参数,最终生成包含随机数字的图片验证码
参数说明:
height
:验证码图片的像素高度(例如80
)width
:验证码图片的像素宽度(例如240
)length
:验证码数字的字符长度(例如4
表示生成4位数字)maxSkew
:数字字符的最大倾斜角度(控制扭曲效果,建议范围0.1~0.5
)dotCount
:干扰点的数量(例如80
表示添加80个随机点)
生成驱动
driver := base64Captcha.NewDriverDigit(80, 240, 5, 0.7, 80)
3.2 base64Captcha.NewCaptcha ()
组合驱动和存储
captcha := base64Captcha.NewCaptcha(driver, store)
base64Captcha.NewCaptcha 是 Go 语言库 base64Captcha 中用于生成验证码的核心函数。它通过组合驱动(Driver) 和 存储(Store) 实现验证码的创建、存储与验证。
实现原理:
● 组合驱动与存储:将验证码生成逻辑(驱动)与答案存储(存储)解耦。
● 生成唯一ID:使用 UUID 或时间戳生成唯一标识。
● 生成答案与图片:调用驱动的 GenerateItem 方法生成答案和图片。
● Base64编码:将图片转换为 Base64 字符串返回。
● 存储答案:将答案存入 Store 供后续验证。
3.3 Generate()
最后根据我们上一步生成的captch,调用Generate()就可以生成验证码和唯一标识的id以及正确答案
id, b64s, ans, err := captcha.Generate()// id: 验证码唯一标识// b64s: Base64格式的图片// answer: 正确答案
3.4 Set()
在拿到上述值以后,我们还需要存储id和answer以方便后续我们与用户输入的数字进行比对,因此我们还需要调用Set接口来存储验证码答案和id
store.Set(id, ans)
3.5 具体实现
package contactimport (\"context\"\"fca/api/internal/svc\"\"fca/api/internal/types\"\"time\"\"github.com/go-redis/redis/v8\" //生成图形需要包含\"github.com/mojocn/base64Captcha\"\"github.com/zeromicro/go-zero/core/logx\")/ CaptchaStore is a custom store for captchas using Redistype CaptchaStore struct {redisClient *redis.Clientprefix string}// NewCaptchaStore creates a new CaptchaStore with Redisfunc NewCaptchaStore(redisAddr, pass, prefix string) *CaptchaStore {client := redis.NewClient(&redis.Options{Addr: redisAddr,Password: pass,})// config := redis.RedisConf{// Host: redisAddr,// Type: \"node\",// Pass: pass,// }// client := redis.MustNewRedis(config)return &CaptchaStore{redisClient: client,prefix: prefix,}}// Get retrieves a captcha value by its id from Redisfunc (s *CaptchaStore) Get(id string, clear bool) string {ctx := context.Background()key := s.prefix + idvalue, err := s.redisClient.Get(ctx, key).Result()if err != nil {return \"\"}if clear {s.redisClient.Del(ctx, key)}return value}// InitCaptchaStore initializes the captcha store with Redisfunc InitCaptchaStore(redisAddr, pass, prefix string) {store = NewCaptchaStore(redisAddr, pass, prefix)}// Set sets the captcha id and value in Redisfunc (s *CaptchaStore) Set(id string, value string) error {ctx := context.Background()key := s.prefix + idreturn s.redisClient.Set(ctx, key, value, 5*time.Minute).Err() // Set expiration to 10 minutes}type WebsiteCaptchaLogic struct {logx.Loggerctx context.ContextsvcCtx *svc.ServiceContext}func NewWebsiteCaptchaLogic(ctx context.Context, svcCtx *svc.ServiceContext) *WebsiteCaptchaLogic {return &WebsiteCaptchaLogic{Logger: logx.WithContext(ctx),ctx: ctx,svcCtx: svcCtx,}}// var store *CaptchaStorevar store = base64Captcha.DefaultMemStorefunc GenerateCaptcha() (string, string, error) {driver := base64Captcha.NewDriverDigit(80, 240, 5, 0.7, 80)captcha := base64Captcha.NewCaptcha(driver, store)id, b64s, ans, err := captcha.Generate()store.Set(id, ans)logx.Infof(\"data %s = %s\", id, ans)return id, b64s, err}func (l *WebsiteCaptchaLogic) WebsiteCaptcha() (resp *types.ContactCaptchaResp, err error) {var aresp types.ContactCaptchaRespid, b64s, err := GenerateCaptcha()if err != nil {return &aresp, nil}aresp.Data.CaptchaId = idaresp.Data.ImageBase64 = b64sreturn &aresp, nil}
三、结语
到此为止,本文关于随机数字验证码生成的内容到此结束了,如有不足之处,欢迎小伙伴们指出呀!
关注我 _麦麦_分享更多干货:_麦麦_-CSDN博客
大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下期见!