网站实现验证码功能

news2024/11/17 0:39:14

一、验证码

一般来说,网站在登录的时候会生成一个验证码来验证是否是人类还是爬虫,还有一个好处是防止恶意人士对密码进行爆破。

二、流程图

三、详细说明

3.1 后端生成验证码

@Override
public Result<Map<String, String>> getVerificationCode() {
    // HuTool 定义图形验证码的长和宽, 验证码的位数,干扰线的条数
    // 线段干扰的验证码
    LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(116, 36, 4, 50);
    String uuid = UUID.randomUUID().toString();
    String verificationCodeKey = "VerificationCode:" + uuid;
    // 存到 redis 中
    ValueOperations<String, String> ops = redisTemplate.opsForValue();
    ops.set(verificationCodeKey, lineCaptcha.getCode());
    // 设置 15 分钟的过期时间
    redisTemplate.expire(verificationCodeKey, 15, TimeUnit.MINUTES);
    Map<String, String> map = new HashMap<>(2);
    map.put("verificationCodeBase64", lineCaptcha.getImageBase64());
    map.put("uuid", uuid);
    return Result.success(map);
}

记得设置验证码过期时间,否则每一次生成验证码都会在 redis 里面产生数据,造成内存浪费。
返回给前端的 json

{
    "code": 200,
    "msg": "操作成功",
    "data": {
        "uuid": "bc814884-fffb-4943-834a-40cc92decfa6",
        "verificationCodeBase64": "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"
    }
}

Base64 是一种用于将二进制数据编码为 ASCII 字符的编码方法,我们这边用这个编码传递验证码图片,数据在 verificationCodeBase64

3.2 前端生成验证码图片

3.2.1 获取验证码 Base64 并且拼接
const updateVerificationCodeImage = async () => {
    // 图像类型
    const imageType = 'image/png';
    const res = await userGetVerificationCodeApi();
    if (res.data) {
      if (res.data.data) {
        verificationCodeBase64.value = res.data.data.verificationCodeBase64;
        uuid.value = res.data.data.uuid;
        // 拼接 Base64 图像数据
        verificationCodeImageSrc.value = `data:${imageType};base64,${verificationCodeBase64.value}`;
      }
    }
};
3.2.2 渲染到页面上
<div class="verificationCode-class">
  <img :src="verificationCodeImageSrc" alt="验证码加载失败" />
  <el-link class="mx-1" @click="updateVerificationCodeImage"
    >看不清楚, 换一张</el-link
  >
</div>

3.3 前端用户点击登录

登录表单的数据加上 uuid 和验证码,确保唯一性。

const form = reactive({
    username: '',
    password: '',
    uuid: '',
    verificationCode: '',
});

3.4 后端验证用户输入的验证码是否正确

@Override
public Result<AppUserLoginVO> userLogin(AppUserLoginDTO appUserLoginDTO) {
    if (Objects.nonNull(appUserLoginDTO)) {
        // 先对验证码进行核对
        ValueOperations<String, String> ops = redisTemplate.opsForValue();
        String uuid = appUserLoginDTO.getUuid();
        String verificationCode = appUserLoginDTO.getVerificationCode();
        String verificationCodeKey = "VerificationCode:" + uuid;
        // redis 里面存的验证码
        String redisVerificationCode = ops.get(verificationCodeKey);
        if (!Objects.equals(verificationCode, redisVerificationCode)) {
            // 用户填入的验证码与 redis 中的不相同
            return Result.success(new AppUserLoginVO(), "登录失败,验证码错误");
        } else {
            // 相同
            ops.getOperations().delete(verificationCodeKey);
        }
    }
}

四、结果

五、参考资料

  • hutool-图形验证码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1276852.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

国内哪个超声波清洗机品牌比较好?质量好超声波清洗机总结

近年来超声波清洗机可以说是非常火爆&#xff0c;可以清洗化妆刷、眼镜、牙套等等一些小物件&#xff0c;大物件物品可以入手大型超声波清洗机&#xff0c;总之现在超声波清洗机已经衍生到可以在家使用&#xff0c;不再是在眼镜店看到它的身影或者是一些工业领域上&#xff0c;…

第二节:服务拆分(案例)

一、服务拆分注意事项 1.1 拆分原则 每个微服务&#xff0c;不要重复开发相同业务&#xff08;例如在单体项目中用到了一个查询&#xff0c;这个查询功能能够查询出订单信息、商品信息、用户信息&#xff0c;那么在拆分微服务时就不要将其写在一起了&#xff0c;订单的微服务只…

1、RocketMQ源码分析(一)

RocketMQ简单介绍 RabbitMQ的底层是使用erlang语言编写的&#xff0c;不便分析其底层&#xff0c;RocketMQ作为原阿里下经历阿里双十一严格考验的中间件&#xff0c;同时也是使用我们熟悉的java语言编写&#xff0c;我们先把入门的基础必备了解透&#xff0c;然后在去分析源码…

基于WebSocket实现客户聊天室

目录 一、实现聊天室原理 二、聊天室前端代码 三、聊天室后端代码&#xff08;重点&#xff09; 四、聊天室实现效果展示 一、实现聊天室原理 1.1 介绍websocket协议 websocket是一种通信协议&#xff0c;再通过websocket实现弹幕聊天室时候&#xff0c;实现原理是客户端首…

使用K-means把人群分类

1.前言 K-mean 是无监督的聚类算法 算法分类&#xff1a; 2.实现步骤 1.数据加工&#xff1a;把数据转为全数字&#xff08;比如性别男女&#xff0c;转换为0 和 1&#xff09; 2.模型训练 fit 3.预测 3.代码 原数据类似这样(source&#xff1a;http:img-blog.csdnimg.cn…

vmware 安装 AlmaLinux OS 8.6

选择系统镜像 选择镜像 选择安装位置和修改名称 可以自定义硬件&#xff0c;也可以不选择&#xff0c;后面可以再设置 自定义硬件可以设置内存和cpu等信息 安装虚拟机系统 密码如果简单的话需要点击两次done 才能保存

集成开发环境PyCharm的使用【侯小啾python领航计划系列(三)】

集成开发环境 PyCharm 的使用【侯小啾python领航计划系列(三)】 大家好,我是博主侯小啾, 🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ🌹꧔ꦿ�…

Stable Diffusion AI绘画系列【10】:AI眼中的美丽清晨

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…

【数电笔记】卡诺图绘制(逻辑函数的卡诺图化简)

目录 说明&#xff1a; 最小项卡诺图的组成 1. 相邻最小项 2. 卡诺图的组成 2.1 二变量卡诺图 2.2 三表变量卡诺图 2.3 四变量卡诺图 3. 卡诺图中的相邻项&#xff08;几何相邻&#xff09; 说明&#xff1a; 笔记配套视频来源&#xff1a;B站 最小项卡诺图的组成 1. …

算法通关村第十四关-青铜挑战认识堆

大家好我是苏麟 , 今天带大家认识认识堆 . 堆 堆是将一组数据按照完全二叉树的存储顺序&#xff0c;将数据存储在一个一维数组中的结构。 堆有两种结构&#xff0c;一种称为大顶堆&#xff0c;一种称为小顶堆 : 大顶堆 大顶堆的任何一个父节点的值&#xff0c;都大于或等于…

nginx设置用户密码

1.官网 https://nginx.org/en/docs/http/ngx_http_auth_basic_module.html2.语法 3.创建密码 [rootlocalhost ~]# yum install httpd-tools -y4.创建密码文件 完毕&#xff01; [rootlocalhost ~]# htpasswd -b -c /etc/nginx/auth-passwd xp xp666-c 创建passwdfile &#…

免费使用优彩云采集器,3分钟学会优彩云采集器使用【2023最新】

如何高效地采集并聚合原创内容成为了一项关键任务&#xff1f;在这个背景下&#xff0c;本文将深入研究优彩云采集和147SEO采集&#xff0c;实现原创文章采集。 147SEO采集器 对于许多从业者而言&#xff0c;147SEO采集并不陌生。作为一款专注于原创内容采集的工具&#xff0c…

avue页面布局 api 引用

展示 index.vue <template><basic-container><avue-crud :option"option":table-loading"loading":data"data":page"page":permission"permissionList":search.sync"search":before-closebefore…

【LeeCode】24. 两两交换链表中的节点

给你一个链表&#xff0c;两两交换其中相邻的节点&#xff0c;并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题&#xff08;即&#xff0c;只能进行节点交换&#xff09;。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4] 输出&#xff1a;[2,1,4…

【LeeCode】19.删除链表的倒数第N个节点

给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5] 示例 2&#xff1a; 输入&#xff1a;head [1], n 1 输出&#xff1a;[] 示例 3&#xf…

4款非常牛的Linux终端应用,thefuck尤其突出

这篇文章向大家介绍了4款非常棒且非常有用的Linux终端应用程序&#xff0c;可以使我们的日常命令操作更加高效。这些工具不仅可以让你在同事面前炫耀一番&#xff0c;而且它们还提供了实用且美观的功能。 第一款&#xff1a;thefuck 你是不是经常在终端敲错命令&#xff1f;敲…

virtualbox中windows11开机自动登录设置

笔者在实际应用过程中&#xff0c;使用了Vritualbox系统安装windows11&#xff0c;然后在windows11中部署了相关应用&#xff0c;需要在开机之后自动启动该应用。 但是实际测试发现&#xff0c;必须windows11的用户登录该系统之后该应用才能启动&#xff0c;否则尽管windows11…

Beta冲刺随笔-DAY6-橘色肥猫

这个作业属于哪个课程软件工程A这个作业要求在哪里团队作业–站立式会议Beta冲刺作业目标记录Beta冲刺Day6团队名称橘色肥猫团队置顶集合随笔链接Beta冲刺笔记-置顶-橘色肥猫-CSDN博客 文章目录 SCRUM部分站立式会议照片成员描述 PM报告项目程序&#xff0f;模块的最新运行图片…

Hdoop学习笔记(HDP)-Part.16 安装HBase

目录 Part.01 关于HDP Part.02 核心组件原理 Part.03 资源规划 Part.04 基础环境配置 Part.05 Yum源配置 Part.06 安装OracleJDK Part.07 安装MySQL Part.08 部署Ambari集群 Part.09 安装OpenLDAP Part.10 创建集群 Part.11 安装Kerberos Part.12 安装HDFS Part.13 安装Ranger …

校园门禁可视化系统解决方案

随着科技的持续进步&#xff0c;数字化校园在教育领域中的地位日益上升&#xff0c;各种智能门禁、安防摄像头等已遍布校园各个地方&#xff0c;为师生提供安全便捷的通行体验。然而数据收集分散、缺乏管理、分析困难等问题也逐渐出现&#xff0c;在这个数字化环境中&#xff0…