captcha 是比较好的验证码库,除了图片验证码,还支持中文语音验证,使用方便,要适配 fastHTTP 或其它的 web 框架也很方便。
captcha 代码结构很清晰,部署时需要调用的 Serve
函数是返回一个 handle
,要适应其它框架,只需改动 server.go
文件,其它地方没有 net/http
依赖,这样也可以不用修改官方库,直接在自己的 handle 里写相应的功能。下面就是使用 fasthttp 来实现:
适配实例
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 来取代。然后在路由里添加:
1
mux.GET("/captcha/{filepath:*}", CaptchaHandle)
这里我用 fasthttp/router
做路由。