Golang图形验证码支持高度定制
2014 年 9 月 13 日
:jack_o_lantern:Base64captcha 项目地址:jack_o_lantern:
几行代码就可以定义自己内容的图形验证码库,支持任意unicode字符的内容.
1. :ledger: 文档&Demo :ledger:
2. :rocket: 快速上手 :rocket:
2.1 :inbox_tray: 下载base64Captcha包 :inbox_tray:
go get -u github.com/mojocn/base64Captcha
2.2 :snowboarder: 在你的项目中使用base64Captcha :snowboarder:
2.2.1 :horse_racing: 实现 Store interface 或者使用自带memory store :horse_racing:
- Build-in Memory Store (只支持单机部署,多台服务器请自定义redis store)
type Store interface { // Set sets the digits for the captcha id. Set(id string, value string) // Get returns stored digits for the captcha id. Clear indicates // whether the captcha must be deleted from the store. Get(id string, clear bool) string //Verify captcha's answer directly Verify(id, answer string, clear bool) bool }
2.2.2 :surfer: 实现 Driver interface 或者使用自带 drivers :surfer:
包自带driver:
// Driver captcha interface for captcha engine to to write staff type Driver interface { //DrawCaptcha draws binary item DrawCaptcha(content string) (item Item, err error) //GenerateIdQuestionAnswer creates rand id, content and answer GenerateIdQuestionAnswer() (id, q, a string) }
2.2.3 :bicyclist: 核心代码 captcha.go :bicyclist:
captcha.go 是package的入口文件,源代码逻辑非常简单,如下:
func init() { //init rand seed rand.Seed(time.Now().UnixNano()) } // Captcha captcha basic information. type Captcha struct { Driver Driver Store Store } func NewCaptcha(driver Driver, store Store) *Captcha { return &Captcha{Driver: driver, Store: store} } //Generate generates a random id, base64 image string or an error if any func (c *Captcha) Generate() (id, b64s string, err error) { id,content, answer := c.Driver.GenerateIdQuestionAnswer() item, err := c.Driver.DrawCaptcha(content) if err != nil { return "", "", err } c.Store.Set(id, answer) b64s = item.EncodeB64string() return } //if you has multiple captcha instances which shares a same store. You may want to use `store.Verify` method instead. //Verify by given id key and remove the captcha value in store, return boolean value. func (c *Captcha) Verify(id, answer string, clear bool) (match bool) { match = c.Store.Get(id, clear) == answer return }
2.2.4 :mountain_bicyclist: 生成Base64(image/audio)验证码字符串 :mountain_bicyclist:
//Generate generates a random id, base64 image string or an error if any func (c *Captcha) Generate() (id, b64s string, err error) { id,content, answer := c.Driver.GenerateIdQuestionAnswer() item, err := c.Driver.DrawCaptcha(content) if err != nil { return "", "", err } c.Store.Set(id, answer) b64s = item.EncodeB64string() return }
2.2.5 校验验证码内容
//if you has multiple captcha instances which shares a same store. You may want to use `store.Verify` method instead. //Verify by given id key and remove the captcha value in store, return boolean value. func (c *Captcha) Verify(id, answer string, clear bool) (match bool) { match = c.Store.Get(id, clear) == answer return }
2.2.6 :runner: 完整实例代码 :runner:
// example of HTTP server that uses the captcha package. package main import ( "encoding/json" "fmt" "github.com/mojocn/base64Captcha" "log" "net/http" ) //configJsonBody json request body. type configJsonBody struct { Id string CaptchaType string VerifyValue string DriverAudio *base64Captcha.DriverAudio DriverString *base64Captcha.DriverString DriverChinese *base64Captcha.DriverChinese DriverMath *base64Captcha.DriverMath DriverDigit *base64Captcha.DriverDigit } var store = base64Captcha.DefaultMemStore // base64Captcha create http handler func generateCaptchaHandler(w http.ResponseWriter, r *http.Request) { //parse request parameters decoder := json.NewDecoder(r.Body) var param configJsonBody err := decoder.Decode(¶m) if err != nil { log.Println(err) } defer r.Body.Close() var driver base64Captcha.Driver //create base64 encoding captcha switch param.CaptchaType { case "audio": driver = param.DriverAudio case "string": driver = param.DriverString.ConvertFonts() case "math": driver = param.DriverMath.ConvertFonts() case "chinese": driver = param.DriverChinese.ConvertFonts() default: driver = param.DriverDigit } c := base64Captcha.NewCaptcha(driver, store) id, b64s, err := c.Generate() body := map[string]interface{}{"code": 1, "data": b64s, "captchaId": id, "msg": "success"} if err != nil { body = map[string]interface{}{"code": 0, "msg": err.Error()} } w.Header().Set("Content-Type", "application/json; charset=utf-8") json.NewEncoder(w).Encode(body) } // base64Captcha verify http handler func captchaVerifyHandle(w http.ResponseWriter, r *http.Request) { //parse request json body decoder := json.NewDecoder(r.Body) var param configJsonBody err := decoder.Decode(¶m) if err != nil { log.Println(err) } defer r.Body.Close() //verify the captcha body := map[string]interface{}{"code": 0, "msg": "failed"} if store.Verify(param.Id, param.VerifyValue, true) { body = map[string]interface{}{"code": 1, "msg": "ok"} } //set json response w.Header().Set("Content-Type", "application/json; charset=utf-8") json.NewEncoder(w).Encode(body) } //start a net/http server func main() { //serve Vuejs+ElementUI+Axios Web Application http.Handle("/", http.FileServer(http.Dir("./static"))) //api for create captcha http.HandleFunc("/api/getCaptcha", generateCaptchaHandler) //api for verify captcha http.HandleFunc("/api/verifyCaptcha", captchaVerifyHandle) fmt.Println("Server is at :8777") if err := http.ListenAndServe(":8777", nil); err != nil { log.Fatal(err) } }
2.3 :clapper:使用历史版本:clapper:
go get github.com/mojocn/base64Captcha@v1.2.2
3. :art: 定制自己的图形验证码 :art:
你那个定制自己的图形验码内容,只需实现 interface driver 和 interface item .
下面是几个可以参考的driver实现示例:
你甚至可以设计 captcha struct 成你想要的功能
4. :sparkling_heart: 致谢 :sparkling_heart:
5. :lollipop: Licence :lollipop:
base64Captcha source code is licensed under the Apache Licence, Version 2.0