> 技术文档 > 《go-zero云笺密钥录》_go-zero base64captcha

《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博客

             大家的「关注❤️ + 点赞👍 + 收藏⭐」就是我创作的最大动力!谢谢大家的支持,我们下期见!