• Vue3问题:如何实现拼图验证+邮箱登录功能?前后端!


    前端功能问题系列文章,点击上方合集↑

    序言

    大家好,我是大澈!

    本文约3500+字,整篇阅读大约需要5分钟。

    本文主要内容分三部分,第一部分是需求分析,第二部分是实现步骤,第三部分是问题详解。

    如果您只需要解决问题,请阅读第一、二部分即可。

    如果您有更多时间,进一步学习问题相关知识点,请阅读至第三部分。

    1. 需求分析

    在登录页面,输入邮箱,点击发送验证码,此时会弹出拼图验证。

    用户向右滑动滑块,到达指定缺口位置,就会验证成功。若验证失败,则会刷新拼图,需要重新滑动。

    当拼图验证成功后,发送验证码按钮就会显示数字倒计时效果,然后此时会在对应邮箱收到验证码。

    在正确输入邮箱验证码之后,点击登录按钮,正确认证并登录成功。

    挺常用、也挺有趣的一个功能需求。

    图片

    2. 实现步骤

    2.1 实现前的一些说明

    本次需求大致分为部分:点击发送验证码按钮时的拼图验证、常用的邮箱验证码发送。

    实现的话,我们会从前端、后端两方面入手,然后给出具体代码实例。

    拼图验证在前端实现,利用了vue3-slide-verify库。

    邮箱验证码发送在后端实现,利用了Spring框架中的JavaMailSender类,然后邮件发送服务使用的是QQ邮箱。

    关于QQ邮箱,在编写后端接口前,一定要记得提前做一些配置

    • 先在QQ邮箱首页-设置-账号-服务中,把服务全部开启。

    • 然后再扫码登录,获取授权码,一定要把这个授权码保存好,不然后面后端接口没法写了。

    图片

    话不多说,开搞朋友们!

    2.2 编写前端代码

    先安装功能依赖:

    npm install --save vue3-slide-verify
    

    再看模版代码,分为两部分:一个是表单部分,一个是拼图弹框部分。

    在表单部分中,给发送验证码按钮一个点击事件,点击让拼图弹框显示。然后禁用此按钮,同时countdown变量开始倒计时递减变化。

    在拼图弹框部分中,主要是定义了两个事件函数。fail是操作失败的回调,success是操作成功的回调。再就是slider-text中,定义的是滑块中显示的文字提示。

    模版代码:

    1. <template>
    2.   <div class="box">
    3.     <!--表单部分-->
    4.     <el-form :model="dataForm" label-width="120px">
    5.       <el-form-item label="邮箱:">
    6.         <el-input v-model="dataForm.email" />
    7.       </el-form-item>
    8.       <el-form-item label="验证码:">
    9.         <el-input v-model="dataForm.code" />
    10.         <el-button type="warning" @click="visible = true" :disabled="isSendingCode || countdown > 0">
    11.           {{ countdown > 0 ? `重新发送(${countdown})` : '发送验证码' }}
    12.         </el-button>
    13.       </el-form-item>
    14.       <el-form-item>
    15.         <el-button type="primary" @click="onSubmit" >登录</el-button>
    16.       </el-form-item>
    17.     </el-form>
    18.     <!--拼图部分-->
    19.     <el-card v-if="visible">
    20.       <slide-verify
    21.           ref="slide"
    22.           slider-text="向右滑动->"
    23.           :imgs="images"
    24.           @success="onSuccess"
    25.           @fail="onFail"
    26.           style="margin: auto;"
    27.       ></slide-verify>
    28.     </el-card>
    29.   </div>
    30. </template>

    再看逻辑代码,主要分为两部分:一个是拼图验证成功和失败的回调,一个是调用了发送邮箱验证码和认证登录这两个接口。

    最先做的,是先引入拼图依赖的对象和样式。

    拼图验证成功后,在里面去调用发送邮箱验证码的接口。

    按钮倒计时效果,以及发送邮箱验证码、认证登录这两个接口的调用,此处不再赘述,可参考之前如何实现短信验证登录的那篇文章。

    再就是,拼图的图片资源数组,可为空。如果数组为空,则会自动下载使用随机网络图片。

    逻辑代码:

    1. <script setup>
    2. import {reactive, reffrom 'vue'
    3. import Axios from '../api/axios';
    4. import {ElMessage} from "element-plus";
    5. // 引入依赖对象
    6. import SlideVerify from "vue3-slide-verify";
    7. // 引入依赖样式
    8. import "vue3-slide-verify/dist/style.css";
    9. const dataForm = reactive({
    10.   // 863074625@qq.com
    11.   email: '863074625@qq.com',
    12.   code'',
    13. })
    14. // 拼图显示标识
    15. const visible = ref(false);
    16. // 拼图的图片资源 可为空,此时会自动下载使用随机网络图片
    17. const images = reactive([
    18.     'https://t7.baidu.com/it/u=2609096218,1652764947&fm=193&f=GIF',
    19.     'https://t7.baidu.com/it/u=2541348729,1193227634&fm=193&f=GIF',
    20.     'https://t7.baidu.com/it/u=2673836711,2234057813&fm=193&f=GIF',
    21. ])
    22. // 拼图验证成功回调
    23. const onSuccess = () => {
    24.   ElMessage.success("验证成功!");
    25.   // 隐藏拼图
    26.   visible.value = false;
    27.   // 拼图验证成功,发送邮箱验证码
    28.   sendVerificationCode();
    29. }
    30. // 拼图验证失败回调
    31. const onFail=()=>{
    32.   ElMessage.error("验证不通过!")
    33. }
    34. // 发送验证码按钮禁用标识
    35. let isSendingCode = ref(false);
    36. // 倒计时变量
    37. let countdown = ref(0);
    38. // 发送验证码,调验证码接口
    39. const sendVerificationCode = () => {
    40.   // 检查邮箱是否有效
    41.   // ...
    42.   // 调发送邮箱接口
    43.   Axios.get('/admin/sendEmail', {
    44.     params: {
    45.       email: dataForm.email,
    46.     }
    47.   })
    48.   .then(res => {
    49.     ElMessage.success(res.data)
    50.   })
    51.   .catch(error => {
    52.     console.error(error);
    53.   });
    54.   isSendingCode.value = true;
    55.   // 设置倒计时时间,这里假设为10
    56.   countdown.value = 10;
    57.   // 倒计时效果
    58.   const countdownInterval = setInterval(() => {
    59.     countdown.value--;
    60.     if (countdown.value <= 0) {
    61.       clearInterval(countdownInterval);
    62.       isSendingCode.value = false;
    63.     }
    64.   }, 1000);
    65. }
    66. // 登录,调检验验证码和密码的登录接口
    67. const onSubmit = () => {
    68.   // 调发送邮箱接口
    69.   Axios.post('/admin/checkEmailLogin', {
    70.     email: dataForm.email,
    71.     code: dataForm.code,
    72.   })
    73.   .then(res => {
    74.     ElMessage.success(res.data)
    75.   })
    76.   .catch(error => {
    77.     console.error(error);
    78.   });
    79. }
    80. </script>

    关于vue3-slide-verify拼图库的属性和回调详细整理,如果朋友你有空余时间,可见文章第部分。

    2.3 编写后端接口

    对于后端实现,要先引入邮箱发送依赖,再做一些服务的配置,再编写两个接口,一个是发送邮箱验证码接口,一个是认证登录接口。

    Pom.xml中引入依赖代码:

    1. <!--redis-->
    2. <dependency>
    3.     <groupId>org.springframework.boot</groupId>
    4.     <artifactId>spring-boot-starter-data-redis</artifactId>
    5. </dependency>
    6. <!-- 邮件发送pom支持 -->
    7. <dependency>
    8.     <groupId>org.springframework.boot</groupId>
    9.     <artifactId>spring-boot-starter-mail</artifactId>
    10. </dependency>

    application.yml中写入QQ邮箱服务的配置,注意邮箱password,用的就是之前保存的授权码

    1. spring:
    2.   datasource:
    3.     url: jdbc:mysql://localhost:3306/mall_tiny?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai
    4.     username: root
    5.     password: 123456
    6.   redis:
    7.     host: localhost # Redis服务器地址
    8.     database: 0 # Redis数据库索引(默认为0
    9.     port: 6379 # Redis服务器连接端口
    10.     password: # Redis服务器连接密码(默认为空)
    11.     timeout: 3000ms # 连接超时时间(毫秒)
    12.   # 发送邮箱
    13.   mail:
    14.     username: 317994054@qq.com
    15.     # 授权码
    16.     password: axpaqqxaejiecaag
    17.     host: smtp.qq.com

    再编写接口Controller层代码:

    1. /**
    2. * 发送邮箱
    3. */
    4. @ApiOperation(value = "发送邮箱")
    5. @GetMapping("/sendEmail")
    6. public CommonResult<String> toSendEmail(@RequestParam("email"String email){
    7.   String message = adminService.toSendEmail(email);
    8.   return CommonResult.success(message);
    9. }
    10. /**
    11. * 检验邮箱验证码,校验成功后登录
    12. */
    13. @ApiOperation(value = "检验邮箱验证码,校验成功后登录")
    14. @PostMapping("/checkEmailLogin")
    15. public CommonResult<String> checkEmailLogin(@RequestBody ToCheckEmailLoginDTO toCheckEmailLoginDTO){
    16.   String checkLogin = adminService.checkEmailLogin(toCheckEmailLoginDTO.getEmail(), toCheckEmailLoginDTO.getCode());
    17.   // 省略用户密码加密校验
    18.   // ...
    19.   // 省略JWT认证
    20.   // ...
    21.   return CommonResult.success(checkLogin);
    22. }

    再编写接口Service层代码:

    在发送邮箱验证码接口业务层中,先生成一个随字符串Code,再调用JavaMailSendersend方法发送验证码,并把验证码存入Redis中。

    在认证登录接口业务层中,将前端传过来的验证码与Redis中存的验证码进行比较,校验成功执行下一步登录操作。

    1. @Autowired
    2. JavaMailSender javaMailSender;
    3. /**
    4. * 发送邮箱
    5. */
    6. @Override
    7. public String toSendEmail(String email) {
    8.   //1.判定验证码是否过期
    9.   String code = redisTemplate.opsForValue().get(email);
    10.   if (!StringUtils.isEmpty(code)){
    11.       return email+":"+"验证码未过期";
    12.   }
    13.   //2.已过期/无验证码 生成验证码
    14.   //随机生成字符串 做验证码
    15.   int toCode = (int) (Math.random() * (50000 - 40000+ 40000);
    16.   code=Integer.toString(toCode);
    17.   // 发送邮箱
    18.   SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
    19.   simpleMailMessage.setSubject("项目登录验证码");
    20.   simpleMailMessage.setText("尊敬的:"+email+"您的注册校验验证码为:" + code + "有效期5分钟");
    21.   simpleMailMessage.setTo(email);
    22.   simpleMailMessage.setFrom("317994054@qq.com");
    23.   javaMailSender.send(simpleMailMessage);
    24.   String toSendMes = "OK";
    25.   if (ComConstants.OK.equals(toSendMes)){
    26.       //redis 中存放 5分钟过期
    27.       redisTemplate.opsForValue().set(email,code,ComConstants.NUM_FIVE, TimeUnit.MINUTES);
    28.       //3.发送短信
    29.       return "邮箱发送成功";
    30.   }
    31.   return "邮箱发送异常";
    32. }
    33. /**
    34. * 检验邮箱验证码,校验成功后登录
    35. */
    36. @Override
    37. public String checkEmailLogin(String email, String code) {
    38.   //1.redis 验证码校验
    39.   String redisCode = redisTemplate.opsForValue().get(email);
    40.   if (code.equals(redisCode)){
    41.       return "登入成功";
    42.   }
    43.   return "登入失败";
    44. }

    3. 问题详解

    3.1 拼图库的属性和回调详细整理

    关于vue3-slide-verify拼图库的属性说明:

    图片

    关于vue3-slide-verify拼图库的回调说明:

    图片

    最后附上,vue3-slide-verify拼图库官方文档地址:https://www.npmjs.com/package/vue3-slide-verify

    3.2 关于实现各种验证登录功能的心得

    在项目中我们做登录功能时,会用到各种验证码登录、各种机器验证。这些验证的作用都是为了安全,这些验证的实现也都是大同小异。

    对于验证码登录,包括但不限于短信验证码、邮箱验证码、图形验证码登录,无论是前端还是后端,实现起来完全就可以是把代码复制粘贴。

    所以,这些我都有写文章做整理,方便朋友们大家使用,也方便自己使用。

    对于登录表单各种机器验证,包括但不限于拼图验证、选择验证等,前端实现起来更是五花八门。本来这些验证的实现我都想整理的,最后感觉没有必要,因为这些东西,真的是充满着共同点,熟悉了其中一种,其它的类型做起来也只会是得心应手了。

    最后的最后,感谢朋友们的支持,感谢朋友们花时间的耐心阅读,谢谢!

    结语

    建立这个平台的初衷:

    • 打造一个仅包含前端问题的问答平台,让大家高效搜索处理同样问题。

    • 通过不断积累问题,一起练习逻辑思维,并顺便学习相关的知识点。

    • 遇到难题,遇到有共鸣的问题,一起讨论,一起沉淀,一起成长。

    感谢关注微信公众号:“程序员大澈”,然后加入问答群,让我们一起解决实现所有BUG!

  • 相关阅读:
    达梦数据库的名词解释
    java毕业设计基于BS架构的疫情包联信息管理系统的设计与实现mybatis+源码+调试部署+系统+数据库+lw
    【云原生之Docker实战】使用Docker部署planka项目管理工具
    【创建springboot-maven项目的pom.xml配置信息】
    【JavaWeb】一文搞懂Response
    jmeter单接口和多接口测试
    SpringBoot 整合 websocket (二)—— 部署Nginx\Tomcat
    Windows计划任务权限维持
    Swarm集群负载均衡的实现方式
    Vue2项目引入element ui的表格第一行有输入框要禁用
  • 原文地址:https://blog.csdn.net/m0_74802419/article/details/134430398