captcha在gin+VUE项目下的使用方式

简介: 之前在项目中,一直使用VUE前端的图片验证码。前几天看到文章,说前端验证容易被绕过,那就准备使用后端验证吧。用golang就选择github.com/dchest/captcha了,折腾一番后,要点记录如下:控制器:package controllersimport ( "by...

之前在项目中,一直使用VUE前端的图片验证码。前几天看到文章,说前端验证容易被绕过,那就准备使用后端验证吧。

用golang就选择github.com/dchest/captcha了,折腾一番后,要点记录如下:

控制器:

package controllers

import (

    "bytes"

    "log"

    "net/http"

    "strconv"

    "strings"

    "time"

    "utils"

    "github.com/dchest/captcha"

    "github.com/gin-gonic/gin"

)

type CheckCodeController struct {

}

/***

*后端图形码验证

*/

func (serviceCheckCode *CheckCodeController) VerifyCode(c *gin.Context) {

    captchaId := c.Query("captchaId")

    pngCode := c.Query("pngCode")

    if captcha.VerifyString(captchaId, pngCode) {

        result := utils.ResultSuccess()   //自己写的用于规范一般状态码传递的package

        c.JSON(http.StatusOK, gin.H{

            "data": result,

        })

    } else {

        result := utils.ResultFailue()

        result.Msg = "图形验证码错误"

        c.JSON(http.StatusOK, gin.H{

            "data": result,

        })

    }

}

/***

刷新验证码,也作为初次获取验证码使用

*/

func (serviceCheckCode *CheckCodeController) ReloadVerifyCode(c *gin.Context) {

    id := captcha.NewLen(4)    //一般用4位数字

    result := utils.ResultSuccess()

    result.Msg = id    //偷懒一下,直接用这个来传递captchaId到前端

    c.JSON(http.StatusOK, gin.H{

        "data": result,

    })

}

/**

显示图形验证码
因为要传递图片,所以要对Header做一些设置

*/

func (serviceCheckCode *CheckCodeController) GenVerifyCode(c *gin.Context) {

    c.Writer.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")

    c.Writer.Header().Set("Pragma", "no-cache")

    c.Writer.Header().Set("Expires", "0")

    c.Writer.Header().Set("Content-Type", "image/png")


    id := c.Param("captchaId")

    id = strings.Replace(id, "/", "", 1)


    var content bytes.Buffer

    captcha.WriteImage(&content, id, 100, 50)  //4位验证码,宽100,高50最清晰

    http.ServeContent(c.Writer, c.Request, id+".png", time.Time{}, bytes.NewReader(content.Bytes()))

    return

}

路由:

checkCodeRoute := router.Group("/check-code")
        {
            checkCodeController := new(controllers.CheckCodeController)
            //刷新图形验证码
            checkCodeRoute.GET("refresh.html", checkCodeController.ReloadVerifyCode)
            //获取图形验证码
            checkCodeRoute.GET("/show/*captchaId", checkCodeController.GenVerifyCode)
            //验证图形码
            checkCodeRoute.GET("/verify", checkCodeController.VerifyCode)
        }

前端:

<template>
  <div>
  <div>
      <el-input v-model="pngCode" placeholder="请输入图片验证码" style="width: 120px;"></el-input>
        <span @click="getCaptchaImgUrl" class="box-verify"><img id="captchaIdImg" :src="captchaImgUrl" /></span>
      <el-button @click="verifyCaptcha">验证</el-button>
    </div>
  </div>
</template>

<script>
 export default {
  data() {
      return {
        captchaId: '',
        captchaImgUrl: '',
        pngCode: ''
      }
    },
    methods: {
      getCaptchaImgUrl() {
        this.axios.get('/check-code/refresh.html', {})
        .then(res => {
          this.captchaId = res.data.data.Msg
          let url = window.location.href
          let host = window.location.host
          let n = host.indexOf(":", 0)
          let k = url.indexOf(host.slice(0,n), 0)
          //这里的端口8000是后端gin的端口
          this.captchaImgUrl = url.slice(0,k) + host.slice(0,n) + ':8000/web/check-code/show/' + res.data.data.Msg
        }).catch(err => {
          console.log(err)
        })
        // console.log(this.captchaImgUrl)
      }, 
      verifyCaptcha() {
        // 因为显示图片验证码的时候, header被改成了'Content-Type': 'image/png',所以
        this.axios({
          methods:"GET",
          url:'/check-code/verify', 
          headers:{
            'Content-Type': 'application/x-www-form-urlencoded'
          },
          params: {
            "captchaId": this.captchaId,
            "pngCode": this.pngCode
          }
        }).then(res => {
          if (res.data.data.Code == 200 ) {
            console.log(res.data.data.Msg)
          } else {
            console.log(res.data.data.Msg)
          }
        }).catch(err => {
          console.log(err)
        })
      }
    },
    mounted() {
      this.getCaptchaImgUrl()
    }
  }
</script>

<!-- 样式 -->
<style>
  .box-verify img{
    vertical-align: middle;
  }
</style>

大功告成!

目录
相关文章
|
11月前
|
JavaScript
Vue中如何实现兄弟组件之间的通信
在Vue中,兄弟组件可通过父组件中转、事件总线、Vuex/Pinia或provide/inject实现通信。小型项目推荐父组件中转或事件总线,大型项目建议使用Pinia等状态管理工具,确保数据流清晰可控,避免内存泄漏。
827 2
|
10月前
|
缓存 JavaScript
vue中的keep-alive问题(2)
vue中的keep-alive问题(2)
694 137
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
1525 0
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
人工智能 JSON JavaScript
VTJ.PRO 首发 MasterGo 设计智能识别引擎,秒级生成 Vue 代码
VTJ.PRO发布「AI MasterGo设计稿识别引擎」,成为全球首个支持解析MasterGo原生JSON文件并自动生成Vue组件的AI工具。通过双引擎架构,实现设计到代码全流程自动化,效率提升300%,助力企业降本增效,引领“设计即生产”新时代。
890 1
|
JavaScript 安全
在 Vue 中,如何在回调函数中正确使用 this?
在 Vue 中,如何在回调函数中正确使用 this?
619 0
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
908 1
|
JavaScript 前端开发
重读vue电商网站45之项目优化上线
重读vue电商网站45之项目优化上线
286 0
重读vue电商网站45之项目优化上线
|
JavaScript Java 物联网
现有vue项目seo优化
现有vue项目seo优化
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
1574 4