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>

大功告成!

目录
相关文章
|
24天前
|
JavaScript
vue使用iconfont图标
vue使用iconfont图标
127 1
|
3天前
|
JavaScript 安全 API
iframe嵌入页面实现免登录思路(以vue为例)
通过上述步骤,可以在Vue.js项目中通过 `iframe`实现不同应用间的免登录功能。利用Token传递和消息传递机制,可以确保安全、高效地在主应用和子应用间共享登录状态。这种方法在实际项目中具有广泛的应用前景,能够显著提升用户体验。
27 8
|
4天前
|
存储 设计模式 JavaScript
Vue 组件化开发:构建高质量应用的核心
本文深入探讨了 Vue.js 组件化开发的核心概念与最佳实践。
26 1
|
4天前
|
资源调度 JavaScript 前端开发
创建vue3项目步骤以及安装第三方插件步骤【保姆级教程】
这是一篇关于创建Vue项目的详细指南,涵盖从环境搭建到项目部署的全过程。
39 1
|
1月前
|
JavaScript 关系型数据库 MySQL
基于VUE的校园二手交易平台系统设计与实现毕业设计论文模板
基于Vue的校园二手交易平台是一款专为校园用户设计的在线交易系统,提供简洁高效、安全可靠的二手商品买卖环境。平台利用Vue框架的响应式数据绑定和组件化特性,实现用户友好的界面,方便商品浏览、发布与管理。该系统采用Node.js、MySQL及B/S架构,确保稳定性和多功能模块设计,涵盖管理员和用户功能模块,促进物品循环使用,降低开销,提升环保意识,助力绿色校园文化建设。
|
2月前
|
JavaScript API 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
2月前
|
JavaScript 前端开发 开发者
Vue是如何进行组件化的
Vue是如何进行组件化的
|
JavaScript Java 物联网
现有vue项目seo优化
现有vue项目seo优化
|
JavaScript 前端开发
重读vue电商网站45之项目优化上线
重读vue电商网站45之项目优化上线
141 0
重读vue电商网站45之项目优化上线
|
2月前
|
JavaScript 前端开发 开发者
vue学习第一章
欢迎来到我的博客!我是瑞雨溪,一名热爱前端的大一学生,专注于JavaScript与Vue,正向全栈进发。博客分享Vue学习心得、命令式与声明式编程对比、列表展示及计数器案例等。关注我,持续更新中!🎉🎉🎉
59 1
vue学习第一章