Go整合captcha實現(xiàn)驗證碼功能
最近在使用Go語言搞一個用戶登錄&注冊的功能,說到登錄&注冊相關(guān),我們油然會產(chǎn)生一種增加驗證碼的想法,因此著手實現(xiàn),后來在GitHub上找到了這個名叫captcha的插件,于是就利用文檔進行了初步的學(xué)習(xí),并融入到自己的項目中,整個過程下來感覺這個插件的設(shè)計非常巧妙,所以就想寫一篇文章分享一下,通過本篇文章,你會學(xué)到:
- 利用captcha生成驗證碼返回到前端使用
- 將captcha生成的驗證碼點擊刷新
- 將captcha生成的驗證碼利用Redis進行緩存
1 captcha概述
GitHub:https://github.com/dchest/captcha
captcha的使用設(shè)計流程
2 實現(xiàn)代碼(使用內(nèi)存緩存)
2.1 后端代碼
生成驗證碼圖片API:
//GenerateImg 生成驗證碼圖片名稱 func GenerateImg(w http.ResponseWriter, req *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") //允許訪問所有域 w.Header().Add("Access-Control-Allow-Headers", "Content-Type") d := struct { CaptchaId string }{ captcha.New(), } bytes, _ := json.Marshal(map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": d.CaptchaId}) w.Write(bytes) }
HTTP服務(wù):
func RunHttp(port string) { logger := log.Default() http.Header{}.Set("Access-Control-Allow-Origin", "*") http.HandleFunc("/user/login", controller.UserLogin) //登錄API http.HandleFunc("/img", controller.GenerateImg) //生成驗證碼圖片API http.Handle("/verify/", captcha.Server(captcha.StdWidth, captcha.StdHeight)) //刷新驗證碼API logger.Println("Http Server Running port:", port, "...") http.ListenAndServe(":"+port, nil) }
啟動HTTP服務(wù):
func main() { web.RunHttp("8000") }
驗證碼驗證:
//UserLogin 用戶登錄 func UserLogin(w http.ResponseWriter, req *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") w.Header().Add("Access-Control-Allow-Headers", "Content-Type") ...... var m map[string]string body, err := ioutil.ReadAll(req.Body) if err != nil { panic(err) } json.Unmarshal(body, &m) var k = m["verify_key"] var v = m["verify_value"] res := captcha.VerifyString(k, v) if res { // 驗證通過 ...... } else { // 驗證未通過 ...... } ...... }
2.2 前端代碼
...... <form class="layui-form" id="form"> <h3 style="font-size: 20px;text-align: center;margin-bottom: 30px;">登錄</h3> <div class="layui-form-item"> <label class="layui-form-label">賬號</label> <div class="layui-input-inline"> <input type="text" id="loginName" placeholder="請輸入賬號" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">密碼</label> <div class="layui-input-inline"> <input type="password" id="loginPwd" placeholder="請輸入密碼" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">驗證碼</label> <div class="layui-input-inline"> <input type="text" id="loginV" placeholder="請輸入驗證碼" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" type="button" onclick="login()">立即提交</button> <button type="button" onclick="toRegister()" class="layui-btn layui-btn-primary">注冊</button> </div> </div> </form> <img id="verify" onclick="reload()"></img> ...... <input type="hidden" id="verify_key"> </body> <script src="http://unpkg.com/layui@2.6.8/dist/layui.js"></script> <script src="http://cdn.staticfile.org/jquery/1.10.2/jquery.min.js"></script> <script> const base_url = 'http://localhost:8000' init() function init() { $.ajax({ url: base_url + "/img", type: "GET", success: function (res) { var obj = JSON.parse(res) $("#verify").attr("src", base_url + "/verify/" + obj.data + ".png") $("#verify_key").attr("value", obj.data) } }) } function reload() { var url = $("#verify").attr("src"); $("#verify").attr("src", url + "?reload=" + (new Date()).getTime()) } function login() { var loginName = $("#loginName").val() var loginPwd = $("#loginPwd").val() var verify_key = $("#verify_key").val() var loginV = $("#loginV").val() var data = { 'login_name': loginName, 'pwd': loginPwd, 'verify_key': verify_key, 'verify_value': loginV } $.ajax({ url: base_url + "/user/login", type: "POST", data: JSON.stringify(data), success: function (res) { ...... }, ...... }) } ...... </script>
2.3 注意點
跨域問題:可加入如下代碼
w.Header().Set("Access-Control-Allow-Origin", "*") //允許訪問所有域 w.Header().Add("Access-Control-Allow-Headers", "Content-Type")
3 自定義Store(使用Redis緩存)
3.1 自定義對象并實現(xiàn)Store抽象
Redis初始化:
var ( RDB *redis.Client TokenTimeOut = time.Second * 3600 ) func init() { RDB = redis.NewClient(&redis.Options{ Addr: "127.0.0.1:6379", Password: "", DB: 0, }) }
自定義結(jié)構(gòu)體&實現(xiàn)Store抽象:
type StoreImpl struct { RDB *redis.Client Expiration time.Duration } func (impl *StoreImpl) Set(id string, digits []byte) { impl.RDB.Set(context.Background(), id, string(digits), impl.Expiration) } func (impl *StoreImpl) Get(id string, clear bool) (digits []byte) { bytes, _ := impl.RDB.Get(context.Background(), id).Bytes() return bytes }
3.2 配置captcha,加入自定義Store實現(xiàn)
//GenerateImg 生成驗證碼圖片名稱 func GenerateImg(w http.ResponseWriter, req *http.Request) { w.Header().Set("Access-Control-Allow-Origin", "*") //允許訪問所有域 w.Header().Add("Access-Control-Allow-Headers", "Content-Type") //header的類型 //需要在New之前進行指定 captcha.SetCustomStore(&verify.StoreImpl{ RDB: dao.RDB, Expiration: time.Second * 1000, }) d := struct { CaptchaId string }{ captcha.New(), } bytes, _ := json.Marshal(map[string]interface{}{"code": 0, "msg": "", "count": 0, "data": d.CaptchaId}) w.Write(bytes) }
3.3 注意點
- 需要在captcha.New()之前進行captcha.SetCustomStore()
- 在captcha.SetCustomStore()之后,自定義的方法實現(xiàn)Store接口時需要完整實現(xiàn),也就是能真正的實現(xiàn)存儲或緩存功能,否則驗證碼無法生成
到此這篇關(guān)于Go整合captcha實現(xiàn)驗證碼功能的文章就介紹到這了,更多相關(guān)Go captcha驗證碼內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
一文詳解Golang?定時任務(wù)庫?gron?設(shè)計和原理
這篇文章主要介紹了一文詳解Golang?定時任務(wù)庫?gron?設(shè)計和原理,gron是一個比較小巧、靈活的定時任務(wù)庫,可以執(zhí)行定時的、周期性的任務(wù)。gron提供簡潔的、并發(fā)安全的接口2022-08-08Golang import 導(dǎo)入包語法及一些特殊用法詳解
這篇文章主要介紹了Golang import 導(dǎo)入包語法及一些特殊用法,需要的朋友可以參考下2020-02-02Golang 實現(xiàn)獲取當(dāng)前函數(shù)名稱和文件行號等操作
這篇文章主要介紹了Golang 實現(xiàn)獲取當(dāng)前函數(shù)名稱和文件行號等操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-05-05