🎃Base64captcha🎃 几行代码就可以定义自己内容的图形验证码库,支持任意unicode字符的内容.

1. 📒 文档&Demo 📒

2. 🚀 快速上手 🚀

2.1 📥 下载base64Captcha包 📥

  1. go get -u github.com/mojocn/base64Captcha

2.2 🏂 在您的项目中使用base64Captcha 🏂

2.2.1 🏇 实现Store interface 或者使用自带memory store 🏇

  1. type Store interface {
  2. // Set sets the digits for the captcha id.
  3. Set(id string, value string)
  4. // Get returns stored digits for the captcha id. Clear indicates
  5. // whether the captcha must be deleted from the store.
  6. Get(id string, clear bool) string
  7. //Verify captcha's answer directly
  8. Verify(id, answer string, clear bool) bool
  9. }

2.2.2 🏄 实现Driver interface 或者使用自带 drivers 🏄

包自带driver:

  1. Driver Digit
  2. Driver String
  3. Driver Math
  4. Driver Chinese
  1. // Driver captcha interface for captcha engine to to write staff
  2. type Driver interface {
  3. //DrawCaptcha draws binary item
  4. DrawCaptcha(content string) (item Item, err error)
  5. //GenerateIdQuestionAnswer creates rand id, content and answer
  6. GenerateIdQuestionAnswer() (id, q, a string)
  7. }

2.2.3 🚴 核心代码captcha.go 🚴

captcha.go 是package的入口文件,源代码逻辑非常简单,如下:

  1. func init() {
  2. //init rand seed
  3. rand.Seed(time.Now().UnixNano())
  4. }
  5. // Captcha captcha basic information.
  6. type Captcha struct {
  7. Driver Driver
  8. Store Store
  9. }
  10. func NewCaptcha(driver Driver, store Store) *Captcha {
  11. return &Captcha{Driver: driver, Store: store}
  12. }
  13. //Generate generates a random id, base64 image string or an error if any
  14. func (c *Captcha) Generate() (id, b64s string, err error) {
  15. id,content, answer := c.Driver.GenerateIdQuestionAnswer()
  16. item, err := c.Driver.DrawCaptcha(content)
  17. if err != nil {
  18. return "", "", err
  19. }
  20. c.Store.Set(id, answer)
  21. b64s = item.EncodeB64string()
  22. return
  23. }
  24. //if you has multiple captcha instances which shares a same store. You may want to use `store.Verify` method instead.
  25. //Verify by given id key and remove the captcha value in store, return boolean value.
  26. func (c *Captcha) Verify(id, answer string, clear bool) (match bool) {
  27. match = c.Store.Get(id, clear) == answer
  28. return
  29. }

2.2.4 🚵 生成Base64(image/audio)验证码字符串 🚵

  1. //Generate generates a random id, base64 image string or an error if any
  2. func (c *Captcha) Generate() (id, b64s string, err error) {
  3. id,content, answer := c.Driver.GenerateIdQuestionAnswer()
  4. item, err := c.Driver.DrawCaptcha(content)
  5. if err != nil {
  6. return "", "", err
  7. }
  8. c.Store.Set(id, answer)
  9. b64s = item.EncodeB64string()
  10. return
  11. }

2.2.5 🤸 校验验证码内容 🤸

  1. //if you has multiple captcha instances which shares a same store. You may want to use `store.Verify` method instead.
  2. //Verify by given id key and remove the captcha value in store, return boolean value.
  3. func (c *Captcha) Verify(id, answer string, clear bool) (match bool) {
  4. match = c.Store.Get(id, clear) == answer
  5. return
  6. }

2.2.6 🏃 完整实例代码 🏃

  1. // example of HTTP server that uses the captcha package.
  2. package main
  3. import (
  4. "encoding/json"
  5. "fmt"
  6. "github.com/mojocn/base64Captcha"
  7. "log"
  8. "net/http"
  9. )
  10. //configJsonBody json request body.
  11. type configJsonBody struct {
  12. Id string
  13. CaptchaType string
  14. VerifyValue string
  15. DriverAudio *base64Captcha.DriverAudio
  16. DriverString *base64Captcha.DriverString
  17. DriverChinese *base64Captcha.DriverChinese
  18. DriverMath *base64Captcha.DriverMath
  19. DriverDigit *base64Captcha.DriverDigit
  20. }
  21. var store = base64Captcha.DefaultMemStore
  22. // base64Captcha create http handler
  23. func generateCaptchaHandler(w http.ResponseWriter, r *http.Request) {
  24. //parse request parameters
  25. decoder := json.NewDecoder(r.Body)
  26. var param configJsonBody
  27. err := decoder.Decode(&param)
  28. if err != nil {
  29. log.Println(err)
  30. }
  31. defer r.Body.Close()
  32. var driver base64Captcha.Driver
  33. //create base64 encoding captcha
  34. switch param.CaptchaType {
  35. case "audio":
  36. driver = param.DriverAudio
  37. case "string":
  38. driver = param.DriverString.ConvertFonts()
  39. case "math":
  40. driver = param.DriverMath.ConvertFonts()
  41. case "chinese":
  42. driver = param.DriverChinese.ConvertFonts()
  43. default:
  44. driver = param.DriverDigit
  45. }
  46. c := base64Captcha.NewCaptcha(driver, store)
  47. id, b64s, err := c.Generate()
  48. body := map[string]interface{}{"code": 1, "data": b64s, "captchaId": id, "msg": "success"}
  49. if err != nil {
  50. body = map[string]interface{}{"code": 0, "msg": err.Error()}
  51. }
  52. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  53. json.NewEncoder(w).Encode(body)
  54. }
  55. // base64Captcha verify http handler
  56. func captchaVerifyHandle(w http.ResponseWriter, r *http.Request) {
  57. //parse request json body
  58. decoder := json.NewDecoder(r.Body)
  59. var param configJsonBody
  60. err := decoder.Decode(&param)
  61. if err != nil {
  62. log.Println(err)
  63. }
  64. defer r.Body.Close()
  65. //verify the captcha
  66. body := map[string]interface{}{"code": 0, "msg": "failed"}
  67. if store.Verify(param.Id, param.VerifyValue, true) {
  68. body = map[string]interface{}{"code": 1, "msg": "ok"}
  69. }
  70. //set json response
  71. w.Header().Set("Content-Type", "application/json; charset=utf-8")
  72. json.NewEncoder(w).Encode(body)
  73. }
  74. //start a net/http server
  75. func main() {
  76. //serve Vuejs+ElementUI+Axios Web Application
  77. http.Handle("/", http.FileServer(http.Dir("./static")))
  78. //api for create captcha
  79. http.HandleFunc("/api/getCaptcha", generateCaptchaHandler)
  80. //api for verify captcha
  81. http.HandleFunc("/api/verifyCaptcha", captchaVerifyHandle)
  82. fmt.Println("Server is at :8777")
  83. if err := http.ListenAndServe(":8777", nil); err != nil {
  84. log.Fatal(err)
  85. }
  86. }

快速测试代码:

  1. package main
  2. import (
  3. "log"
  4. "testing"
  5. "github.com/mojocn/base64Captcha"
  6. )
  7. //configJsonBody json request body.
  8. type configJsonBody struct {
  9. Id string
  10. CaptchaType string
  11. VerifyValue string
  12. DriverAudio *base64Captcha.DriverAudio
  13. DriverString *base64Captcha.DriverString
  14. DriverChinese *base64Captcha.DriverChinese
  15. DriverMath *base64Captcha.DriverMath
  16. DriverDigit *base64Captcha.DriverDigit
  17. }
  18. var store = base64Captcha.DefaultMemStore
  19. // base64Captcha create return id, b64s, err
  20. func GetCaptcha() (string, string, error) {
  21. // {
  22. // ShowLineOptions: [],
  23. // CaptchaType: "string",
  24. // Id: '',
  25. // VerifyValue: '',
  26. // DriverAudio: {
  27. // Length: 6,
  28. // Language: 'zh'
  29. // },
  30. // DriverString: {
  31. // Height: 60,
  32. // Width: 240,
  33. // ShowLineOptions: 0,
  34. // NoiseCount: 0,
  35. // Source: "1234567890qwertyuioplkjhgfdsazxcvbnm",
  36. // Length: 6,
  37. // Fonts: ["wqy-microhei.ttc"],
  38. // BgColor: {R: 0, G: 0, B: 0, A: 0},
  39. // },
  40. // DriverMath: {
  41. // Height: 60,
  42. // Width: 240,
  43. // ShowLineOptions: 0,
  44. // NoiseCount: 0,
  45. // Length: 6,
  46. // Fonts: ["wqy-microhei.ttc"],
  47. // BgColor: {R: 0, G: 0, B: 0, A: 0},
  48. // },
  49. // DriverChinese: {
  50. // Height: 60,
  51. // Width: 320,
  52. // ShowLineOptions: 0,
  53. // NoiseCount: 0,
  54. // Source: "设想,你在,处理,消费者,的音,频输,出音,频可,能无,论什,么都,没有,任何,输出,或者,它可,能是,单声道,立体声,或是,环绕立,体声的,,不想要,的值",
  55. // Length: 2,
  56. // Fonts: ["wqy-microhei.ttc"],
  57. // BgColor: {R: 125, G: 125, B: 0, A: 118},
  58. // },
  59. // DriverDigit: {
  60. // Height: 80,
  61. // Width: 240,
  62. // Length: 5,
  63. // MaxSkew: 0.7,
  64. // DotCount: 80
  65. // }
  66. // },
  67. // blob: "",
  68. // loading: false
  69. // }
  70. // https://captcha.mojotv.cn/ 调试配置
  71. var param configJsonBody = configJsonBody{
  72. Id: "",
  73. CaptchaType: "string",
  74. VerifyValue: "",
  75. DriverAudio: &base64Captcha.DriverAudio{},
  76. DriverString: &base64Captcha.DriverString{
  77. Length: 4,
  78. Height: 60,
  79. Width: 240,
  80. ShowLineOptions: 2,
  81. NoiseCount: 0,
  82. Source: "1234567890qwertyuioplkjhgfdsazxcvbnm",
  83. },
  84. DriverChinese: &base64Captcha.DriverChinese{},
  85. DriverMath: &base64Captcha.DriverMath{},
  86. DriverDigit: &base64Captcha.DriverDigit{},
  87. }
  88. var driver base64Captcha.Driver
  89. //create base64 encoding captcha
  90. switch param.CaptchaType {
  91. case "audio":
  92. driver = param.DriverAudio
  93. case "string":
  94. driver = param.DriverString.ConvertFonts()
  95. case "math":
  96. driver = param.DriverMath.ConvertFonts()
  97. case "chinese":
  98. driver = param.DriverChinese.ConvertFonts()
  99. default:
  100. driver = param.DriverDigit
  101. }
  102. c := base64Captcha.NewCaptcha(driver, store)
  103. return c.Generate()
  104. // id, b64s, err := c.Generate()
  105. // body := map[string]interface{}{"code": 1, "data": b64s, "captchaId": id, "msg": "success"}
  106. // if err != nil {
  107. // body = map[string]interface{}{"code": 0, "msg": err.Error()}
  108. // }
  109. // var _ = body
  110. // // log.Println(body)
  111. // log.Println(1)
  112. // log.Println(id)
  113. // log.Printf("store =%+v\n", store)
  114. }
  115. // base64Captcha verify
  116. func VerifyCaptcha(id, VerifyValue string) bool {
  117. return store.Verify(id, VerifyValue, true)
  118. }
  119. // go test -test.run=TestMyCaptcha -count=1 -v ./
  120. func TestMyCaptcha(t *testing.T) {
  121. id, b64s, err := GetCaptcha()
  122. if err != nil {
  123. return
  124. }
  125. var _ = b64s
  126. log.Println("id =", id)
  127. log.Println("VerifyValue =", store.Get(id, true))
  128. result := VerifyCaptcha(id, store.Get(id, true))
  129. log.Println("result =", result)
  130. }

3. 🎨 定制自己的图形验证码 🎨

您那个定制自己的图形验码内容,只需实现 interface driverinterface item.

下面是几个可以参考的driver实现示例:

  1. DriverMath
  2. DriverChinese
  3. ItemChar

您甚至可以设计captcha struct成您想要的功能