当前位置: 首页 > news >正文

验证码实现

验证码案例

学了Spring MVC ,配置 相关章节, 现可以尝试写一个前后端交互的验证码


文章目录

  • 验证码案例
  • 前言
  • 一、验证码是什么?
  • 二、需求
    • 1.引入依赖
    • 2.导入前端页面
    • 3.约定前后段交互接口
  • 三、代码解析
    • Controller
    • model
    • application.xml
  • 四丶结果
  • 五丶总结


前言

提示:这里可以添加本文要记录的大概内容:

页面如下图所示
1.页面生成验证码
2.输入验证码,点击提交,验证用户输入验证码是否正确,正确则页面跳转

在这里插入图片描述


提示:以下是本篇文章正文内容,下面案例可供参考

一、验证码是什么?

验证码,是来区分用户是计算机还是人的公共全自动程序,可以防止:恶意破解密码,刷票,等有效防止某个黑客对特定用户进行暴力登录,这个问题必须只有人类才能解答,验证码花样百出,下面我们将采用扭曲干扰验证码来实现前后端交互的接口在这里插入图片描述

二、需求

1.引入依赖

代码如下(示例):

<dependencies>
		//SpingWeb 框架
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
		// lombok 自动生成
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>
        //test 测试方法
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
		//验证码 相关的类 封装好了的 直接用
        <dependency>
            <groupId>cn.hutool</groupId>
            <artifactId>hutool-captcha</artifactId>
            <version>5.8.26</version>
        </dependency>

    </dependencies>

把这段代码加入pom.xml文件中即可,但是要把里面的注释删了 ,否则会出错

2.导入前端页面

代码如下(示例):
index.html

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="utf-8">

  <title>验证码</title>
  <style>
    #inputCaptcha {
      height: 30px;
      vertical-align: middle; 
    }
    #verificationCodeImg{
      vertical-align: middle; 
    }
    #checkCaptcha{
      height: 40px;
      width: 100px;
    }
  </style>
</head>

<body>
  <h1>输入验证码</h1>
  <div id="confirm">
    <input type="text" name="inputCaptcha" id="inputCaptcha">
    <img id="verificationCodeImg" src="/captcha/getCaptcha" style="cursor: pointer;" title="看不清?换一张" />
    <input type="button" value="提交" id="checkCaptcha">
  </div>
  <script src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
  <script>

    $("#verificationCodeImg").click(function(){
      $(this).hide().attr('src', '/captcha/getCaptcha?dt=' + new Date().getTime()).fadeIn();
    });

    $("#checkCaptcha").click(function () {
          $.ajax({
        url:"/captcha/check",
        type:"post",
        data:{
          captcha:$("#inputCaptcha").val()
        },
        success: function(result){
          if(result==true){
            location.href="/success.html"
          }else{
            alert("验证码错误");
          }
        }
      })
    });
    });

  </script>
</body>

</html>

success.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>验证成功页</title>
</head>
<body>
    <h1>验证成功</h1>
</body>
</html>

3.约定前后段交互接口

需求分析
后端需要提供两个服务

  1. 生成验证码,并返回验证码;
  2. 校验验证码是否正确;

接口定义
1.生成验证码
请求:

请求URL:/captcha/getCaptcha
响应:验证码图片内容

2.校验验证码是否正确
请求:

请求URL:/captcha/check
请求参数:captcha ,用户传过来的验证码
响应: true / false

三、代码解析

Controller

@RestController
@RequestMapping("/captcha")
public class CaptchaController {
    //注入配置 对象 , 一些常量从里面读取
    @Autowired
    private CaptchaProperties cp;
    //易凤种 华为ms
    private static long VALID_TIME_OUT = 60*1000;
    @RequestMapping("/getCaptcha")
    public void getCaptcha(HttpSession session, HttpServletResponse response) {
        //生成验证码 ,并把验证码写入浏览器中
        //定义图形验证码的长和宽
        CircleCaptcha captcha = CaptchaUtil.createCircleCaptcha(cp.getWidth(), cp.getHeight(), cp.getCodeCount(), cp.getCilceCount());
        //打印验证码
        String code = captcha.getCode();
        System.out.println(code);
        //验证码 , 当前时间 存入Session
        session.setAttribute(cp.getSession().getCode(), code);
        session.setAttribute(cp.getSession().getDate(), new Date());
        try {
            //把验证码写到浏览器中
            captcha.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }

    //校验验证码,获取生成的验证码 写给Session
    @RequestMapping("/check")
    public boolean check(String captcha,HttpSession session) {
        //校验是否为空,防止equls空指针
        if(!StringUtils.hasLength(captcha)){
            return false;
        }
        //从Session中读取值
        String code = (String) session.getAttribute(cp.getSession().getCode());
        Date date = (Date) session.getAttribute(cp.getSession().getDate());
        //校验获取验证码的时间 和 校验时间 的差值不能超过一分钟
        if(date == null || (System.currentTimeMillis() - date.getTime()) > VALID_TIME_OUT){
            return false;
        }
        return captcha.equalsIgnoreCase(code);
    }
}

解析 :接口getCaptcha ,用来生成验证码(从hutool上面cv),那么如何将生成的验证码传给另一个接口呢 ? 设置Session,response是用来把验证码写入到文件/浏览器中的 ,前端用来改一下img中图片的src属性即可获取
Controller 从model中获取配置信息, 需要依赖注入 ,各种常量属性,和存储在Session中的“key

model

@Data
@Configuration
@ConfigurationProperties(prefix = "captcha")
//读取配置的信息
public class CaptchaProperties {
    private Integer width;
    private Integer height;
    private Integer codeCount;
    private Integer cilceCount;
    private Session session;

    @Data
    public static class Session {
        private String code;
        private String date;
    }
}

配置对象的接口 ,用来获取配置中的信息(对象) ,并封装成一个类,需要用到@configurationproperties(“prefix="对象名"”)并且设置对象中的属性,内部类 注意使用内部类 一般要加上 public static 或者会出现错误 具体原因后续再说
@Data 是用来生成 get/set 方法的,来自于lombok依赖

application.xml

captcha:
  width: 100
  height: 40
  codeCount: 4
  circleCount: 40
  Session:
    key: SESSION_CAPTCHA_KEY
    date: SESSION_CAPTCHA_DATE

配置相关信息,配置了验证码的相关属性,前后端交互时的Session , 使用 key - value 的形式

四丶结果

在这里插入图片描述
点击“提交”,跳转页面 成功!!
在这里插入图片描述

五丶总结

问题:

  • HttpSErvletResponse 是什么 ? 为什么能写入到浏览器 ?
  • 在验证代码时,在一个接口中把验证码传给Session ,另一个接口为什么能从Session中获取到?
  • 在使用内部类时, 为什么 要设置 public ? 为什么 要用static才能运行?
  • [ ]

注意:

  • System.currentTimeMillis() 表示当前时间 ,类型为long , 单位为ms
http://www.dtcms.com/a/112093.html

相关文章:

  • d202541
  • 量子计算入门:Qiskit实战量子门电路设计
  • 智慧农业大数据平台解决方案
  • 冰球比赛系统的结构设计:UML类图问题解析和绘图
  • 嵌入式Linux开发环境搭建,三种方式:虚拟机、物理机、WSL
  • 【黑马点评】商户查询缓存
  • 机器学习中的自监督学习概述与实现过程
  • 每日文献(八)——Part four
  • 基于YOLOv8的热力图生成与可视化-支持自定义模型与置信度阈值的多维度分析
  • FPGA系统开发板调试过程不同芯片的移植步骤介绍
  • Leetcode 680 -- 双指针 | 贪心
  • LeetCode算法题(Go语言实现)_30
  • AcWing 6135. 奶牛体检
  • 【Java集合】LinkedList源码深度分析
  • Nature Electronics|一种透气、可拉伸的液态金属基3D电子皮肤系统(健康监测/可穿戴电子/透汗透气性电子/电子皮肤/柔性电子/集成电路)
  • 降维算法之PCA(主成分分析)
  • 函数和模式化——python
  • 文件系统-重定向
  • 架构思维:冷热分离 - 表数据量大读写缓慢的优化方案
  • 有没有可以帮助理解高数的视频或者书籍资料?
  • 【力扣hot100题】(050)岛屿数量
  • 消息队列之-Kafka
  • #Linux内存管理# 在ARM32bit Linux中,高端内存的起始地址是如计算出来的?
  • 思二勋:未来所有的业务都将生于AI、长于AI、成于AI
  • 搜索二维矩阵
  • 笔记:代码随想录算法训练营day65:dijkstra(堆优化版)精讲、Bellman_ford 算法精讲
  • Docker安装、配置Redis
  • 使用Expo框架开发APP——详细教程
  • 【JavaScript】原型链 prototype 和 this 关键字的练习(老虎机)
  • 安当TDE透明加密:构建跨地域文件服务器安全传输的“双重保险“