Golang Http 驗證碼示例

驗證碼(CAPTCHA)是「Completely Automated Public Turing test to tell Computers and Humans Apart」(全自動區分 計算機和人類的 圖靈測試)的縮寫,是一種區分用戶是計算機仍是人的公共全自動 程序。能夠防止:惡意破解密碼、 刷票、論壇灌水,有效防止某個黑客對某一個特定註冊用戶用特定程序暴力破解方式進行不斷的登錄嘗試,實際上用驗證碼是如今不少網站通行的方式,咱們利用比較簡易的方式實現了這個功能。這個問題能夠由計算機生成並評判,可是必須只有人類才能解答。因爲計算機沒法解答CAPTCHA的問題,因此回答出問題的用戶就能夠被認爲是人類。

傳統網站驗證碼工做機制

  1. 客戶端請求服務器獲取驗證碼圖片
  2. 服務器生成隨機串(驗證碼值)寫入Session,並將驗證碼值寫入到圖片中返回給客戶端
  3. 客戶端輸入圖片上的字符串提交給服務器驗證
  4. 服務器比對客戶端提交的字符串值和 Session 中是否匹配,若是匹配則經過驗證

因爲服務器生成的驗證碼值從始至終均未返回給客戶端,所以,客戶端只能從圖片中識別驗證碼字符串,從而保證人機校驗邏輯。git

Go的HTTP驗證碼

思路

Go 語言的 HTTP 服務器默認不支持 Session,所以驗證碼值須要換個思路存儲,如下是不使用 Session 的邏輯github

  1. 客戶端請求服務器獲取驗證碼ID
  2. 服務器生成驗證碼 ID,並生成驗證碼值,將 ID 和值的映射關係記錄到內存或緩存,並將 ID 返回給客戶端
  3. 客戶端根據返回的 ID 請求服務器獲取驗證碼圖片
  4. 服務器獲取到驗證碼 ID,從內存或緩存中取出驗證碼值,將該值寫入圖片並將圖片返回給客戶端
  5. 客戶端提交驗證碼 ID(第1步得到)和驗證碼值給服務器驗證
  6. 服務器獲取驗證碼 ID,從內存或緩存中取出驗證碼值與客戶端提交的驗證碼值比對

示例

  1. 安裝驗證碼依賴
github.com/dchest/captcha
  1. 代碼實現
package main
   
   import (
       "fmt"
       "github.com/dchest/captcha"
       "log"
       "net/http"
   )
   
   func main() {
       // 獲取驗證碼 ID
       http.HandleFunc("/captcha/generate", func(w http.ResponseWriter, r *http.Request) {
           id := captcha.NewLen(6)
           if _, err := fmt.Fprint(w, id); err != nil {
               log.Println("generate captcha error", err)
           }
       })
       // 獲取驗證碼圖片
       http.HandleFunc("/captcha/image", func(w http.ResponseWriter, r *http.Request) {
           id := r.URL.Query().Get("id")
           if id == "" {
               http.Error(w, "Bad Request", http.StatusBadRequest)
               return
           }
           w.Header().Set("Content-Type", "image/png")
           if err := captcha.WriteImage(w, id, 120, 80); err != nil {
               log.Println("show captcha error", err)
           }
       })
       // 業務處理
       http.HandleFunc("/login", func(w http.ResponseWriter, r *http.Request) {
           if err := r.ParseForm(); err != nil {
               log.Println("parseForm error", err)
               http.Error(w, "Internal Error", http.StatusInternalServerError)
               return
           }
           // 獲取驗證碼 ID 和驗證碼值
           id := r.FormValue("id")
           value := r.FormValue("value")
           // 比對提交的驗證碼值和內存中的驗證碼值
           if captcha.VerifyString(id, value) {
               fmt.Fprint(w, "ok")
           } else {
               fmt.Fprint(w, "mismatch")
           }
       })
       log.Fatal(http.ListenAndServe(":8080", nil))
   }
  1. 運行緩存

    1. 訪問/captcha/generate得到驗證碼 ID
    2. 訪問/captcha/image?id=驗證碼 ID
    3. 訪問/login,並輸入第一步的驗證碼 ID 和第二步的驗證碼值便可查看驗證結果

項目地址

https://github.com/xialeistudio/go-http-captcha-example服務器

相關文章
相關標籤/搜索