Golang图片验证码的使用方法

 更新时间:2024年05月07日 10:30:34   作者:GEEK JUMP  
最近在使用到Golang进行原生开发,注册和登录页面都涉及到图片验证码的功能,支持很多类型的验证方式,例如支持数字类型、字母类型、音频验证码、中文验证码,本文给大家介绍Golang图片验证码的使用,感兴趣的朋友跟随小编一起看看吧

一、背景

        最近在使用到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 captcha
import (
	"context"
	"github.com/redis/go-redis/v9"
	"sync"
	"time"
)
const captchaKey = "string:captcha:"
var ctx = context.Background()
type RedisStore struct {
	redisClient *redis.Client
	mtx         sync.Mutex
}
func (r *RedisStore) Set(id string, value string) error {
	r.mtx.Lock()
	defer r.mtx.Unlock()
	key := captchaKey + id
	result := 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 + id
	result := 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 + id
	result := 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内存撑爆了. 

到此这篇关于Golang图片验证码的使用的文章就介绍到这了,更多相关Golang图片验证码内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 使用Go实现邮箱验证码API功能

    使用Go实现邮箱验证码API功能

    本文将带你了解一个项目如何实现一个邮箱验证接口,即一个可用的发送邮箱验证码API和验证验证码是否正确功能,对Go实现邮箱验证码API详细过程感兴趣的朋友一起看看吧
    2024-06-06
  • Go处理JSON数据的实现

    Go处理JSON数据的实现

    本文主要介绍了Go处理JSON数据的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-02-02
  • golang爬虫colly 发送post请求

    golang爬虫colly 发送post请求

    本文主要介绍了golang爬虫colly 发送post请求实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • 使用golang-unsafe包的注意事项及说明

    使用golang-unsafe包的注意事项及说明

    这篇文章主要介绍了使用golang-unsafe包的注意事项及说明,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2023-02-02
  • golang如何实现抓取IP地址的蜘蛛程序详解

    golang如何实现抓取IP地址的蜘蛛程序详解

    这篇文章主要给大家介绍了关于利用golang如何实现抓取IP地址的蜘蛛程序的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2018-07-07
  • Go语言中的自定义类型你了解吗

    Go语言中的自定义类型你了解吗

    自定义类型是 Go 语言中非常重要的概念之一,通过自定义类型,我们可以更好地封装数据、组织代码,提高程序的可读性和可维护性。本文将从以下几个方面介绍 Go 自定义类型的相关知识,感兴趣的可以了解一下
    2023-04-04
  • Golang Http请求返回结果处理

    Golang Http请求返回结果处理

    本文主要介绍了Golang Http请求返回结果处理,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • Go并发限制之限流与控制并发数的实践指南

    Go并发限制之限流与控制并发数的实践指南

    在 Go 并发编程中,一个非常现实的问题是:goroutine很轻量,但不是无限资源,当你随手 go func() 起上成千上万的协程时,系统可能不会立刻崩,但会在某个瞬间出现问题,所以一个核心能力就是:如何控制并发数量与访问速率(限流),本文小编为大家详细介绍一下
    2026-04-04
  • GO语言实现AES-CFB加密的操作方法

    GO语言实现AES-CFB加密的操作方法

    本文介绍了如何用Go语言实现AES-CFB加密和解密,首先,定义一个属于encrypt包的文件,使用AES算法、CFB模式和Base64编码等功能,在加密函数中,接收明文和密钥,生成一个AES块密码和一个随机的初始化向量,实现明文的加密
    2024-10-10
  • golang中的struct操作

    golang中的struct操作

    结构体是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体,每个值称为结构体的成员。下面介绍下golang中的struct,感兴趣的朋友一起看看吧
    2021-11-11

最新评论