golang iris(mvc) 框架使用 dchest/captcha

提示:当调用过 captcha.VerifyString 后需要重新生成新的 CaptchaId !

核心控制器代码

package pubcontrollers

import (
	"time"
	"bytes"
	"net/http"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/mvc"
	"github.com/dchest/captcha"
)


type CaptchaController struct{
	Ctx iris.Context
}

func (c *CaptchaController) BeforeActivation(b mvc.BeforeActivation) {
	b.Handle("GET", "/captcha/{captcha_id}", "CaptchaImage")
}

func (c *CaptchaController) CaptchaImage()  {
	captcha_id := c.Ctx.Params().Get("captcha_id")

	if c.Ctx.URLParam("t") != "" {
		captcha.Reload(captcha_id)
	}
    c.responseCaptchaImage(captcha_id, 200, 50)
}

func (c *CaptchaController) responseCaptchaImage(id string, width, height int) error {
	w := c.Ctx.ResponseWriter()
	r := c.Ctx.Request()

	w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")
	w.Header().Set("Pragma", "no-cache")
	w.Header().Set("Expires", "0")
 
	var content bytes.Buffer
	ext := ".png"
	switch ext {
	case ".png":
		w.Header().Set("Content-Type", "image/png")
		captcha.WriteImage(&content, id, width, height)
	case ".wav":
		w.Header().Set("Content-Type", "audio/x-wav")
		captcha.WriteAudio(&content, id, "zh")
	default:
		return captcha.ErrNotFound
	}
 
	download := false
	if download {
		w.Header().Set("Content-Type", "application/octet-stream")
	}
	http.ServeContent(w, r, id+ext, time.Time{}, bytes.NewReader(content.Bytes()))
	return nil
}
  

 

创建 captcha_id 的通用工具包文件

package utils

import (
	"github.com/dchest/captcha"
)

type MyCaptchaModel struct {
	Id string
	Path string
}

// 几位数字的验证码
func Captcha(len int) *MyCaptchaModel {
	captchaId := captcha.NewLen(len)
	stru := MyCaptchaModel {
		Id: captchaId,
		Path : "/pub/captcha/"+ captchaId + "",
	}
	return &stru
}

func VerifyCaptcha(captchaId, postCaptcha string) bool {
	success := captcha.VerifyString(captchaId, postCaptcha)
	return success
}
 

登录控制器调用示例

func (c *LoginController) GetLogin() mvc.Result {
	// 验证码 
	capt := utils.Captcha(4)
	return mvc.View{
		Name: "pub/login/login.html",
		Data: iris.Map{
			"Title": "登录 | " + utils.AppConfig.AppName,
			"CaptchaPath": capt.Path,
			"CaptchaId": capt.Id,
		},
	}
}

模板文件 html 示例

 <div class="form-group">
                <label for="user_password">验证码</label>
                <img id="captcha_img" height="50" width="100%" src="{{.CaptchaPath}}" title="看不清,点击验证码可变更"  />
                <input type="text" class="form-control" id="user_captcha" placeholder="验证码">
              </div>

  

部分 js 代码

        $("#captcha_img").on("click", function(){
            var path = '{{.CaptchaPath}}';
            path += '?t=' + new Date().getTime()
            $("#captcha_img").attr("src", path);
        });
        $("#loginButton").on("click", function(){
            var usercode = $("#user_login").val();
            var userpass = $("#user_password").val();
            var usercapt = $("#user_captcha").val();
            if(usercode.length == 0){
                pubmain.toast('请输入帐号');
                return;
            }
            if(userpass.length == 0){
                pubmain.toast('请输入密码');
                return;
            }
            if(usercapt.length == 0){
                pubmain.toast('请输入验证码');
                return;
            }
            $.post("/pub/login", {
              usercode: usercode, 
              userpass: userpass, 
              usercapt: usercapt,
              captcha_id: '{{.CaptchaId}}', 
            }, function(json){
                if (json.flag){
                    window.location.replace("/")
                }else{
                    pubmain.toast(json.msg);
                }
            });
        });

  

后端验证验证码代码

func (c *LoginController) PostLogin() {
     // ...

    usercapt := c.Ctx.FormValue("usercapt")
    captcha_id := c.Ctx.FormValue("captcha_id")

    if len(usercode) == 0{
        c.responseToClient(false, "请输入您的帐号")
        return
    }

    if len(usercapt) == 0{
        c.responseToClient(false, "请输入验证码")
        return
    }
    
    if len(captcha_id) == 0 {
        c.responseToClient(false, "非法请求")
        return
    }

    if !utils.VerifyCaptcha(captcha_id, usercapt) {
        c.responseToClient(false, "验证码错误")
        return
    }

        // ...
}
 
原文地址:https://www.cnblogs.com/chenrh/p/12826917.html