Golang图片验证码的使用

ops/2024/12/1 19:40:35/

一、背景

        最近在使用到Golang进行原生开发,注册和登录页面都涉及到图片验证码的功能。找了下第三方库的一些实现,发现了这个库用得还是蛮多的。并且支持很多类型的验证方式,例如支持数字类型、字母类型、音频验证码、中文验证码等等。 

        项目地址: https://github.com/mojocn/base64Captcha

        官方文档地址: https://captcha.mojotv.cn/.netlify/functions/captcha

        支持多种验证码类型(多种验证码驱动):

二、基本使用

1、生成验证码base64字符串

生成验证码的基本逻辑顺序如下:

        0、需要准备存储验证码的一种驱动实现Store接口,库中有一个基于Store接口的内存存储方案的默认实现类: base64Captcha.DefaultMemStore

        1、需要定义生成验证码类型的Driver驱动类实例, 配置验证码信息,例如图片大小、高度、模糊度等等

        2、通过base64Captcha.NewCaptcha(&driver, store),生成验证码的base64字符串、验证码ID、验证码的答案、以及error信息, 最后重点拿到验证码ID、验证码base64字符串响应给前端进行展示

        3、最后底层会将数据存储到store存储方式中,这个store类实现了Store接口,将验证码信息进行存储

// 这里我自己实现了一个基于Redis的Store存储驱动类
var store = captcha.NewRedisStore(db.GetRedisConn())func GenCaptcha() (string, string) {// 设置验证码驱动类型,这里是数字运算类型的验证码 // 例如会生成几个数的基本运算, 最后求运算结果作为验证码结果driver := base64Captcha.DriverMath{          Height:     50,Width:      200,NoiseCount: 0,}captchaObj := base64Captcha.NewCaptcha(&driver, store)captchaId, b64s, _, err := captchaObj.Generate()if err != nil {panic(err.Error())}return captchaId, b64s // 拿到验证码ID、验证码的base64字符串
}

        拿到验证码ID、验证码的base64字符串, 前端页面使用一个隐藏的input存储验证码ID、一个input作为表单提交验证码的值、一个img标签,将src设置为这个base64字符串,即可正常显示这个验证码.

        前端局部代码如下:

        显示效果如下:

        后端查看Redis的存储信息:  可以看到验证码ID、验证码答案 8 x 5 = 40

2、后端校验验证码

 后端校验的大致逻辑就是:

        0、需要准备存储验证码的一种驱动实现store,库有有一个基于Store接口的内存存储方案的实现类base64Captcha.DefaultMemStore。 这个使用刚才和生成验证码的store变量一样即可

        1、直接通过store对象,调用Verify方法,传递验证码ID、以及验证码答案即可, 验证结果返回true则代表通过, 返回false则表示不通过. 还有一个参数clear(bool), 代表执行验证后无论是否通过,都需要将这个验证码删除/作废

func VerifyCaptcha(captchaId string, answer string) bool {return store.Verify(captchaId, answer, true)
}

后端获取验证码,进行校验的代码截图:

3、Redis存储驱动代码: RedisStore

非生产环境代码,只是简单示例,请勿使用在生产环境。 因为有些逻辑没有做严格校验以及测试

package captchaimport ("context""github.com/redis/go-redis/v9""sync""time"
)const captchaKey = "string:captcha:"var ctx = context.Background()type RedisStore struct {redisClient *redis.Clientmtx         sync.Mutex
}func (r *RedisStore) Set(id string, value string) error {r.mtx.Lock()defer r.mtx.Unlock()key := captchaKey + idresult := r.redisClient.SetNX(ctx, key, value, time.Second*60)if result.Err() != nil {return result.Err()}return nil
}func (r *RedisStore) Get(id string, clear bool) string {r.mtx.Lock()defer r.mtx.Unlock()key := captchaKey + idresult := r.redisClient.Get(ctx, key)if result.Err() != nil {return ""}if clear {go r.redisClient.Del(ctx, key)}return result.Val()
}func (r *RedisStore) Verify(id, answer string, clear bool) bool {r.mtx.Lock()defer r.mtx.Unlock()key := captchaKey + idresult := r.redisClient.Get(ctx, key)if result.Err() != nil {return false}storeAnswer := result.Val()if clear {go r.redisClient.Del(ctx, key)}return answer == storeAnswer
}func NewRedisStore(redisClient *redis.Client) *RedisStore {return &RedisStore{redisClient: redisClient,mtx:         sync.Mutex{},}
}

三、总结

        使用mojocn/base64Captcha库可以简单的生成验证码base64图片信息,方便了我们进行Web开发。 如果需要更高级或者详细的使用方式,请查看官方文档。

        在实现Store存储驱动的时候,还要考虑我们的图片验证码例如访问频率限制、怎么针对有特征的客户端进行限流, 除了验证码有过期时间以外,  如是否有IP访问限流? 或者其他防御手段, 这样才能确保我们的后端Redis不会被恶意刷新,导致Redis内存撑爆了. 


http://www.ppmy.cn/ops/35252.html

相关文章

面试 Java 基础八股文十问十答第二十七期

面试 Java 基础八股文十问十答第二十七期 作者:程序员小白条,个人博客 相信看了本文后,对你的面试是有一定帮助的!关注专栏后就能收到持续更新! ⭐点赞⭐收藏⭐不迷路!⭐ 1)什么是内部类&…

智慧工地)智慧工地标准化方案(107页)

2.2 设计思路 对于某某智慧工地管理系统的建设,绝不是对各个子系统进行简单堆砌,而是在满足各子系统功能的基础上,寻求内部各子系统之间、与外部其它智能化系统之间的完美结合。系统主要依托于智慧工地管理平台,来实现对众多子系统…

【数据可视化-02】Seaborn图形实战宝典

Seaborn介绍 Seaborn是一个基于Python的数据可视化库,它建立在matplotlib的基础之上,为统计数据的可视化提供了高级接口。Seaborn通过简洁美观的默认样式和绘图类型,使数据可视化变得更加简单和直观。它特别适用于那些想要创建具有吸引力且信…

Redis高级-分布式缓存

分布式缓存 – 基于Redis集群解决单机Redis存在的问题 单机的Redis存在四大问题: 1.Redis持久化 Redis有两种持久化方案: RDB持久化AOF持久化 1.1.RDB持久化 RDB全称Redis Database Backup file(Redis数据备份文件)&#xf…

C++之Eigen使用(使用cmake)

1、eigen安装 安装命令如下: sudo apt-get updatesudo apt-get install libeigen3-dev默认安装路径为: /usr/include/eigen3 2、使用cmake 添加eigen头文件,由于eigen只有头文件,因此只要添加头文件即可。 3、其他 3.1 cmake内…

Elasticsearch内置分析器全面解析

Elasticsearch提供了丰富的内置分析器,以满足不同场景下的文本分析需求。本文将详细介绍几个核心的内置分析器,包括它们的工作原理和使用示例,帮助开发者更好地理解如何在索引和搜索过程中应用这些分析器。 1. Standard Analyzer&#xff08…

2024网络安全面试问题宝典(4万字)

2024网络安全厂商面试问题宝典(4万字) 目录 评分标准网络基础问题 TCP建立连接要进行3次握手(syn-syn,ack-ack),而断开连接要进行4次(fin-ack-fin-ack)TCP,UDP区别:安全常用的协议…

【LeetCode 121】买卖股票的最佳时机

思路 思路: 所谓代码的复杂性来源于业务的复杂性,如果能够想清楚业务实现逻辑,就能够轻松写出代码; 假设当前是第i天,如何在第i天赚到最多的钱?需要在第i天之前以最低价买入股票; 所以需要求…