A flexible and various captcha package

Base64captcha supports any unicode character and can easily be customized to support Math Chinese Korean Japanese Russian Arabic etc.
1. πππ Doc & Demo
2. πππ Quick start
2.1 π¬π¬π¬ Use history version
Tag v1.2.2
go get github.com/mojocn/base64Captcha@v1.2.2
or edit your go.mod
file to
github.com/mojocn/base64Captcha@v1.2.2
2.2 π₯π₯π₯ Download package
go get -u github.com/mojocn/base64Captcha
For Gopher from mainland China without VPN go get golang.org/x/image
failure solution:
- go version > 1.11
- set env
GOPROXY=https://goproxy.io
2.3 πππ How to code with base64Captcha
2.3.1 πππ Implement Store interface or use build-in memory store
type Store interface {
Set(id string, value string)
Get(id string, clear bool) string
Verify(id, answer string, clear bool) bool
}
2.3.2 πππ Implement Driver interface or use one of build-in drivers
There are some build-in drivers:
type Driver interface {
DrawCaptcha(content string) (item Item, err error)
GenerateIdQuestionAnswer() (id, q, a string)
}
2.3.3 π΄π΄π΄ βCore code captcha.go
captcha.go
is the entry of base64Captcha which is quite simple.
package base64Captcha
import (
"math/rand"
"time"
)
func init() {
rand.Seed(time.Now().UnixNano())
}
type Captcha struct {
Driver Driver
Store Store
}
func NewCaptcha(driver Driver, store Store) *Captcha {
return &Captcha{Driver: driver, Store: store}
}
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
}
func (c *Captcha) Verify(id, answer string, clear bool) (match bool) {
match = c.Store.Get(id, clear) == answer
return
}
2.3.4 π΅π΅π΅ βGenerate Base64(image/audio) string
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.3.5 π€Έπ€Έπ€Έ Verify Answer
func (c *Captcha) Verify(id, answer string, clear bool) (match bool) {
match = c.Store.Get(id, clear) == answer
return
}
2.3.6 πππ βFull Example
package main
import (
"encoding/json"
"fmt"
"github.com/mojocn/base64Captcha"
"log"
"net/http"
)
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
func generateCaptchaHandler(w http.ResponseWriter, r *http.Request) {
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
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)
}
func captchaVerifyHandle(w http.ResponseWriter, r *http.Request) {
decoder := json.NewDecoder(r.Body)
var param configJsonBody
err := decoder.Decode(¶m)
if err != nil {
log.Println(err)
}
defer r.Body.Close()
body := map[string]interface{}{"code": 0, "msg": "failed"}
if store.Verify(param.Id, param.VerifyValue, true) {
body = map[string]interface{}{"code": 1, "msg": "ok"}
}
w.Header().Set("Content-Type", "application/json; charset=utf-8")
json.NewEncoder(w).Encode(body)
}
func main() {
http.Handle("/", http.FileServer(http.Dir("./static")))
http.HandleFunc("/api/getCaptcha", generateCaptchaHandler)
http.HandleFunc("/api/verifyCaptcha", captchaVerifyHandle)
fmt.Println("Server is at :8777")
if err := http.ListenAndServe(":8777", nil); err != nil {
log.Fatal(err)
}
}
2.3.7 Example Use Etcd as store
captcha with etcd database as store
3. π¨π¨π¨ Customization
You can customize your captcha display image by implementing interface driver
and interface item.
There are some example for your reference.
You can even design the captcha struct to whatever you prefer.
4. πππ Thanks
5. πππ Licence
base64Captcha source code is licensed under the Apache Licence, Version 2.0
(http://www.apache.org/licenses/LICENSE-2.0.html).