广告位联系
返回顶部
分享到

Golang图片验证码的使用方法介绍

Golang 来源:互联网 作者:佚名 发布时间:2024-05-07 21:59:56 人浏览
摘要

一、背景 最近在使用到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接口,将验证码信息进行存储

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

// 这里我自己实现了一个基于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), 代表执行验证后无论是否通过,都需要将这个验证码删除/作废

1

2

3

func VerifyCaptcha(captchaId string, answer string) bool {

    return store.Verify(captchaId, answer, true)

}

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

3、Redis存储驱动代码: RedisStore

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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

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内存撑爆了. 


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 :
相关文章
  • Golang流程控制语句的具体使用

    Golang流程控制语句的具体使用
    顺序控制 顺序控制 默认情况下,Go代码执行顺序是按照从上到下依次执行的,这种按照顺序执行的代码就叫做顺序语句。如下: 1 2 3 4 5 6
  • Golang图片验证码的使用方法介绍

    Golang图片验证码的使用方法介绍
    一、背景 最近在使用到Golang进行原生开发,注册和登录页面都涉及到图片验证码的功能。找了下第三方库的一些实现,发现了这个库用得还
  • Golang中实现类似类与继承的方法
    在Go语言中,并没有像传统面向对象编程语言(Java、C++)中那样的类和继承的概念。Go语言采用了结构体和组合的方式来实现类似的功能。
  • Golang中四种gRPC模式举例介绍
    1. Unary RPC proto文件如下 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 syntax = proto3; option go_package=.;service; message HelloRequest { // Name of the person to greet string n
  • go-python库使用应用介绍
    在当今软件开发领域,跨语言编程已经成为一种常见的需求。不同的编程语言各自有其优势和适用场景,因此在项目开发过程中,经常需要
  • Go json反序列化“null“的问题解决

    Go json反序列化“null“的问题解决
    有这么一段代码,可以先看一下有没有什么问题,作用是输入一段json字符串,反序列化成map,然后将另一个inputMap的内容,merge进这个map
  • 在golang中将“2023年4月”解析为time.Time对象的详细
    我无法将像April 2023这样的日期字符串解析为 time.Time 对象来比较 golang 中的日期时间对象。 正确答案 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package main
  • 在golang中,我可以使用flag包来定义一个可以选择
    我想做的是能够运行这三个场景: cmd --test --branchrelease cmd --测试全部 --branch release cmd --分支发布 能够在没有参数(如布尔值)的情况下自行
  • Docker golang + ffmpeg执行命令失败
    您好,我正在使用以下 docker 映像: 1 from golang:alpine3.18 使用 ffmpeg:(可能在这里我遗漏了一些东西) 1 run apk add --no-cache ffmpeg 但是当尝试执
  • 如何使用beego orm在postgres中存储图片
    Postgres如何存储文件 postgres提供了两种不同的方式存储二进制,要么是使用bytea类型直接存储二进制,要么就是使用postgres的LargeObject功能;决
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计