【node.js】开发篇:koa2实现动态生成图像校验码(含vue3项目中使用方式)

【node.js】开发篇:koa2实现动态生成图像校验码(含vue3项目中使用方式)

前期准备

首先 我们需要在 koa2 项目中安装 svg-captcha 依赖:

npm install --save svg-captcha

koa2接口编写

随后我们新建文件,路径为 src\utils\captcha.js,并写入如下代码:

这里的代码创建了一个单独的js文件存放,并进行了一些简单的封装,之后向外暴露了 getCaptcha 这个方法。

/**
 *  @description 使用 svg-captcha 生成 图形校验码
 * @author mosaic
 */

const svgCaptcha = require('svg-captcha')
/**
 *
 * @description 生成 图形验证码
 * @return {*}
 */
const getCaptcha = () => {
  //  若创建算数式验证码,将create改为createMathExpr
  const newCaptcha = svgCaptcha.create({
    size: 2, // 验证码长度
    fontSize: 40, // 验证码文字尺寸
    noise: 5, // 干扰线条数量 0-5
    width: 120, // 生成svg的宽度
    height: 45, // 生成svg的高度
    color: true, // 验证码字符颜色
    background: '#fff' // 验证码图片背景颜色
  })

  //	注意 svg-captcha 生成校验码svg后,有两个返回参数,一个data(svg代码),一个text(验证码文字)
  return {
    data: newCaptcha.data,
    text: newCaptcha.text
  }
}

module.exports = {
  getCaptcha
}

路由编写

随后就可以去编写路由了,我的验证码主要是用于用户注册,所以我的如有写在 uesers里,具体路径:routers/users/users.js

/**
 * @description 用户路由文件
 * @author mosaic
 */

const router = require('koa-router')()
const { getCaptcha } = require('../../utils/captcha')

...

// 图形验证码
router.get('/captcha', (ctx, next) => {
  const captcha = getCaptcha()
  ctx.body = {
    data: captcha
  }
})

module.exports = router

记得去app.js,也就是入口文件,去注册路由!

const users = require('./routes/users/users')
app.use(users.routes(), users.allowedMethods())

Vue3+vite+ts 项目中使用

接收服务端传递的内容

来到前端的vue项目里,路径:src/http/api/users.tss 编写下面代码

这里我的 axios 是经过自己的二次封装的,如果你没有自己封装过 axios ,理论上也可以这样写。

/**
 *
 * @description 获取图形校验码
 * @return {string}
 */
import { axios } from '../axios'
// 如果没有自己封装过 import axios from 'axios'

export const getCaptcha = async () => {
  const res = await axios({
    url: '/api/users/captcha',
    method: 'get'
  }).then((res) => {
    return res.data
  })
  return res
}

在前端页面发送请求

来到 src/views/register/register.vue 开始调用接口发送请求

<template>
	<div class="input-group">
      <label class="label" for="Captcha">校验码</label>
      <div class="input-line">
          <input
            autocomplete="off"
            v-model="formData.captchaText"
            type="text"
            class="input"
            id="Captcha"
          />
        <div class="supplement" @click="changeCaptcha()">
          <div v-html="captcha.data"></div>
        </div>
      </div>
    </div>
</template>
<script setup lang="ts">
  import { ref, reactive } from 'vue'
  import { getCaptcha } from '../../http/api/users'
  
  // 表单数据
  const formData = reactive({
    captchaText: ''
  })
  let captcha = ref(await getCaptcha())
  // 点击 修改验证码
  const changeCaptcha = async () => {
    captcha.value = await getCaptcha()
  }
</script>

如何渲染服务端生成的svg标签

<div class="supplement" @click="changeCaptcha()">
   <div v-html="captcha.data"></div>
</div>

上面那段代码,我们渲染 svg 代码时,使用的是v-html 指令,众所周知 动态使用 v-html 可能存砸 xss 攻击风险,此时如果你的项目配置了 ESLint ,也会报错:'v-html' directive can lead to XSS attack.

在网站上动态渲染任意 HTML 是非常危险的,因为容易导致 [XSS 攻击]。只在可信内容上使用 v-html永不用在用户提交的内容上。

解决v-html容易遭受xss攻击的问题

解决方案: 使用 vue-dompurify-html 插件

1. 安装插件:
npm install vue-dompurify-html --save
2. main.ts中引入 vue-dompurify-html 包并挂载到vue原型上
import { createApp } from 'vue'
import App from './App.vue'
import router from './router/index'
// A "safe" replacement for the v-html directive. The HTML code is sanitized with DOMPurify before being interpreted.
import VueDOMPurifyHTML from 'vue-dompurify-html'

createApp(App).use(router).use(VueDOMPurifyHTML).mount('#app')
3. 使用
<div class="supplement" @click="changeCaptcha()">
   <div v-dompurify-html="captcha.data"></div>
</div>

如何实现验证

实现验证,可以使用之前后端传递过来的 text 属性,在需要的时候,与当前用户输入的验证码进行判断即可:

<script setup lang="ts">
  import { ref, reactive } from 'vue'
  import { getCaptcha } from '../../http/api/users'
  
  // 表单数据
  const formData = reactive({
    captchaText: ''
  })
  let captcha = ref(await getCaptcha())
  // 点击 修改验证码
  const changeCaptcha = async () => {
    captcha.value = await getCaptcha()
  }
  
    const register = () => {
    if (formData.captchaText == captcha.value.text) {
      console.log('验证通过!!!')
    }
    console.log('点击了注册按钮!!!')
  }
</script>
posted @   捡破烂的小z  阅读(743)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
点击右上角即可分享
微信分享提示