• 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
        }
    
            // ...
    }
     
  • 相关阅读:
    MySQL与SQLServer的语法区别
    Linux系统ELK环境搭建
    springboot_yml配置, 以及 properties 和yml转换示例
    mybatis-plus的 mapper.xml 路径配置问题
    Windows下 启动redis
    Mysql 创建库,删除库 命令,脚本
    mybatis中传入多个参数时,接口调用报错Parameter '*****' not found ...
    构建启动Vue项目
    HyperLedger/Fabric区块连网络-编译启动单节点
    HyperLedger/Fabric区块连网络 死磕fabric
  • 原文地址:https://www.cnblogs.com/chenrh/p/12826917.html
Copyright © 2020-2023  润新知