ijd8.COM

A simple blog for an old Ma Nong.

Go 验证码库 captcha 适配 fastHTTP 的方法

Permalink

captcha 是比较好的验证码库,除了图片验证码,还支持中文语音验证,使用方便,要适配 fastHTTP 或其它的 web 框架也很方便。

captcha 代码结构很清晰,部署时需要调用的 Serve 函数是返回一个 handle ,要适应其它框架,只需改动 server.go 文件,其它地方没有 net/http 依赖,这样也可以不用修改官方库,直接在自己的 handle 里写相应的功能。下面就是使用 fasthttp 来实现:

适配实例

Go: fasthttp captcha
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
57
58
59
package controller

import (
	"bytes"
	"github.com/dchest/captcha"
	"github.com/valyala/fasthttp"
	"path"
	"strings"
)

var (
	captchaImgWidth  = captcha.StdWidth
	captchaImgHeight = captcha.StdHeight
)

func CaptchaHandle(ctx *fasthttp.RequestCtx) {
	dir, file := path.Split(string(ctx.URI().Path()))
	ext := path.Ext(file)
	id := file[:len(file)-len(ext)]
	if ext == "" || id == "" {
		ctx.NotFound()
		return
	}
	if len(ctx.FormValue("reload")) > 0 {
		captcha.Reload(id)
	}
	lang := strings.ToLower(string(ctx.FormValue("lang")))
	download := path.Base(dir) == "download"
	if captchaServeFastHTTP(ctx, id, ext, lang, download) == captcha.ErrNotFound {
		ctx.NotFound()
	}
}

func captchaServeFastHTTP(ctx *fasthttp.RequestCtx, id, ext, lang string, download bool) error {
	ctx.Response.Header.Set("Cache-Control", "no-cache, no-store, must-revalidate")
	ctx.Response.Header.Set("Pragma", "no-cache")
	ctx.Response.Header.Set("Expires", "0")

	var content bytes.Buffer
	switch ext {
	case ".png":
		ctx.Response.Header.Set("Content-Type", "image/png")
		_ = captcha.WriteImage(&content, id, captchaImgWidth, captchaImgHeight)
	case ".wav":
		ctx.Response.Header.Set("Content-Type", "audio/x-wav")
		_ = captcha.WriteAudio(&content, id, lang)
	default:
		return captcha.ErrNotFound
	}

	if download {
		ctx.Response.Header.Set("Content-Type", "application/octet-stream")
	}

	ctx.SetStatusCode(fasthttp.StatusOK)
	ctx.SetBody(content.Bytes())

	return nil
}

代码是照葫芦画瓢,直接用 fasthttp 来取代。然后在路由里添加:

Go: captcha 路由
1
mux.GET("/captcha/{filepath:*}", CaptchaHandle)

这里我用 fasthttp/router 做路由。

参考

Write a Comment

Submit Comment Login
Based on Golang + fastHTTP + sdb | go1.16.3 Processed in 0ms