1、图形验证码设计
1.1思路
现今,市面上的图形验证码付费的,免费的多种多样,主要形式有滑动拼图、文字点选、语序点选、字体识别、空间推理、智能随机等。
而处理也分为web端和sever端两部分
此处以免费的kaptcha 为例,进行数字图形验证码的解析
2、server 端
2.1 controller
@RestController
@Slf4j
@RequestMapping("/sys")
public class SysLoginController {@Resourceprivate ISysCaptchaService sysCaptchaService;@GetMapping("/captcha/{uuid}")public void captcha(HttpServletResponse response, @PathVariable("uuid") String uuid) throws IOException {response.setHeader("Cache-Control", "no-store, no-cache");response.setContentType("image/jpeg");//获取图片验证码BufferedImage image = sysCaptchaService.getCaptcha(uuid);ServletOutputStream out = response.getOutputStream();ImageIO.write(image, "jpg", out);IOUtils.closeQuietly(out);}}
2.2 service
public interface ISysCaptchaService extends IService<SysCaptcha> {/*** 获取图片验证码** @param uuid uuid* @return Image*/BufferedImage getCaptcha(String uuid);
}
2.3 serviceImpl
//此处引入了kaptcha的Producer
import com.google.code.kaptcha.Producer;@Service
public class SysCaptchaServiceImpl extends ServiceImpl<SysCaptchaMapper, SysCaptcha> implements ISysCaptchaService {@Resourceprivate Producer producer;@Overridepublic BufferedImage getCaptcha(String uuid) {if (StrUtil.isBlank(uuid)) {throw new RuntimeException("uuid不能为空");}//生成文字验证码String code = producer.createText();SysCaptcha captchaEntity = new SysCaptcha();captchaEntity.setUuid(uuid);captchaEntity.setCode(code);//5分钟后过期captchaEntity.setExpireTime(DateUtil.offset(DateUtil.date(), DateField.MINUTE, 5).toLocalDateTime());//将数据写入数据库,此处最好可以写入到redis等缓存中,不需要过期手动处理this.save(captchaEntity);return producer.createImage(code);}
}
2.4 配置KaptchaConfig
@Configuration
public class KaptchaConfig {@Beanpublic DefaultKaptcha producer() {Properties properties = new Properties();properties.put("kaptcha.border", "no");properties.put("kaptcha.textproducer.font.color", "black");properties.put("kaptcha.textproducer.char.space", "5");properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑");Config config = new Config(properties);DefaultKaptcha defaultKaptcha = new DefaultKaptcha();defaultKaptcha.setConfig(config);return defaultKaptcha;}
}
不进行config配置时,会报如下异常
**************************
APPLICATION FAILED TO START
***************************
Description:
A component required a bean of type 'com.google.code.kaptcha.Producer' that could not be found.Action:
Consider defining a bean of type 'com.google.code.kaptcha.Producer' in your configuration.
2.5 pom.xml
<properties><kaptcha.version>2.3.5</kaptcha.version></properties><dependencies><dependency><groupId>com.youkol.support.kaptcha</groupId><artifactId>kaptcha-spring-boot-starter</artifactId><version>${kaptcha.version}</version></dependency></dependencies>
2.6 数据库表
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for sys_captcha
-- ----------------------------
DROP TABLE IF EXISTS `sys_captcha`;
CREATE TABLE `sys_captcha` (`uuid` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT 'uuid',`code` varchar(6) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '验证码',`expire_time` datetime NULL DEFAULT NULL COMMENT '过期时间',PRIMARY KEY (`uuid`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = '系统验证码' ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;
2.7 测试
3、web端
3.1 vue3 安装 uuid 小插件
3.1.1 安装
pnpm add vue3-uuid
如果pnpm安装异常
切换pnpm源
pnpm config set registry https://registry.npmmirror.com //切换淘宝源
3.1.2 main.ts中引入
import { createApp } from 'vue'import App from './App.vue'
import router from './router'
import pinia from '@/stores'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
//@ts-expect-error忽略当前文件ts类型的检测否则有红色提示(打包会失败)
import zhCn from 'element-plus/dist/locale/zh-cn.mjs'
import 'virtual:svg-icons-register'
import '@/styles/index.scss'
//使用UUID
import UUID from 'vue3-uuid'const app = createApp(App)app.use(pinia)
app.use(router)
app.use(UUID)
app.use(ElementPlus, {'locale': zhCn
})app.mount('#app')
3.1.3 使用
import { uuid } from 'vue3-uuid'const getCaptcha = () => {const id = uuid.v4()console.log('@@@@', id)
}
3.2 加载验证码
3.2.1 Template
<template><div class="container"><el-row><el-col :span="12" :xs="0"></el-col><el-col :span="12" :xs="24"><el-formclass="login_form":model="userStore.user":rules="loginRules"ref="loginForm"><h1>欢迎登录{{ setting.title }}</h1><el-form-item><el-inputv-model="userStore.user.username"placeholder="请输入用户名"prefix-icon="User"></el-input></el-form-item><el-form-item><el-inputv-model="userStore.user.password"placeholder="请输入密码"prefix-icon="Lock"show-password></el-input></el-form-item><div class="captcha"><el-form-item><el-input type="text" placeholder="请输入验证码"></el-input></el-form-item><el-form-item><el-image :src="captchaUrl" @click="getCaptcha" style="width: 150px;height: 30px"></el-image><el-button style="width: 150px;" @click="refresh">刷新</el-button></el-form-item></div><div class="class-btn"><el-button type="primary" @click="login">登录</el-button><el-button type="primary" @click="register">注册</el-button></div></el-form></el-col></el-row></div>
</template>
3.2.2 script
<script setup lang="ts">
import { uuid } from 'vue3-uuid'let captchaUrl = ref('')
const getCaptcha = async () => {const id = uuid.v4()console.log(id)captchaUrl.value = import.meta.env.VITE_SERVER + '/sys/captcha/' + id
}
const refresh = () => {getCaptcha()
}onMounted(() => {getCaptcha()
})</script>