后端代码练习5--验证码案例

        我们日常生活中,在进行应用程序注册或者登录的时候,出于安全性的考虑,我们都会被进行一项验证的操作,即通过网页给我们的图片进行一些列的操作,最终完成对我们身份的验证并给我们这些用户返回验证码,让我们来完成注册或者登录;

        今天我们来学习验证码案例;

1. 需求

        界面如下图所示:

         页面能有一下的显示效果:

        1、页面生成验证码

        2、输入验证码,点击提交,验证用户输入的验证码是否正确,正确则进行页面跳转

2. 准备工作

        创建Spring Boot项目,引入SpringMVC的依赖包,把前端页面放在项目中:

        index1.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="/admin/captcha" style="cursor: pointer;" title="看不清?换一张" />
    <input type="button" value="提交" id="checkCaptcha">
  </div>
  <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
  <script>
    
    $("#verificationCodeImg").click(function(){
      $(this).hide().attr('src', '/admin/captcha?dt=' + new Date().getTime()).fadeIn();
    });
 
    $("#checkCaptcha").click(function () {
        alert("验证码校验");
    });
 
  </script>
</body>
 
</html>

          success1.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. 约定前后端交互接口

3.1 需求分析

        后端生成验证码图片,发送到前端页面,前端根据图片输入内容,点击提交,校验验证码是否正确,正确切换登录页面,错误提示验证码错误。

        后端需要提供两个服务:

1、生成验证码图片,返回给前端

2、校验验证码是否正确。

3.2 接口定义

1、生成验证码

请求URL:/captcha/getCaptcha

param:无

return:图片(响应)

2、校验验证码

请求URL:/captcha/check

param:inputCode

return:true / false(响应)

   3.3 Hutool工具介绍

        验证码的实现,是使用Hutool提供的小工具来实现的。Hutool是一个Java工具包类库,对文件、流、加密解密、转码、正则、线程、XML等JDK方法进行封装,组成各种Util(静态)工具类。 Hutool是一个小而全的Java工具类库,通过静态方法进行封装,降低相关API的学习成本,提高工作效率;

Hutool官方:https://hutool.cn/参考文档:简介 | Hutool 

3.3.1 引入依赖

        在官方文档中,官方建议使用下面这个版本,如图:

         我们使用这个版本,可以在这里直接复制,粘贴到我们项目的pom.xml文件中,也可以去maven的中央仓库找,如图:中央仓库地址:https://mvnrepository.com/

        进入中央仓库,搜索hutool,选择:

        选择合适版本的依赖:

          当前是5.8.16版本,因为只需要使用验证码功能,所以就只用含有验证码功能的,不选all全部,在pom.xml文件添加下面内容: 

		<!-- https://mvnrepository.com/artifact/cn.hutool/hutool-captcha -->
		<dependency>
			<groupId>cn.hutool</groupId>
			<artifactId>hutool-captcha</artifactId>
			<version>5.8.16</version>
		</dependency>

3.3.2 测试使用Hutool生成验证码

        在test包(这个包也是专门给后端人员进行测试代码用的)路径下创建CaptchaTest类,进行测试,使用官方文档给我们提供的代码:

package com.example.zxslzw2014_8_11;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import cn.hutool.core.lang.Console;
public class CaptchaTest {
    public static void main(String[] args) {
        //定义图形验证码的长和宽
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(200, 100);
        //图形验证码写出,可以写出到文件,也可以写出到流
        lineCaptcha.write("E:/101.png");
        //输出code
        Console.log(lineCaptcha.getCode());
        //验证图形验证码的有效性,返回boolean值
        lineCaptcha.verify("1234");
        //重新生成验证码
        lineCaptcha.createCode();
        lineCaptcha.write("E:/102.png");
        //新的验证码
        Console.log(lineCaptcha.getCode());
        //验证图形验证码的有效性,返回boolean值
        lineCaptcha.verify("1234");
 
    }
}

        运行main方法后发现,在目的位置下,有两个图片,如图:

控制台输出内容:

4. 实现服务器端代码

4.1 后端代码

        yml配置内容:

captcha:
  width: 200
  height: 100
  session:
    key: captcha_session_key
    date: captcha_session_date

        把配置项挪到配置文件中,把生成的验证码存储在Session中,校验时使用配置项。 

        验证码配置项对应的Java对象:

@Component
@ConfigurationProperties(prefix = "captcha")
@Data
public class CaptchaProperties {
    private Integer width;
    private Integer height;
    private Session session;
 
    @Data
    public static class Session {
        private String key;
        private String date;
    }
}

        Controller代码:

@RequestMapping("/captcha")
@RestController
public class CaptchaController {
    @Autowired
    private CaptchaProperties captchaProperties;
    public static final long session_valid_timeout = 60 * 1000;//1分钟
    //验证码页面
    @RequestMapping("/get")
    public void getCaptcha(HttpSession session, HttpServletResponse response) {
        //定义图形验证码的长和宽
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(captchaProperties.getWidth(), captchaProperties.getHeight());
        //设置返回类型
        response.setContentType("image/jpeg");
        //禁止缓存
        response.setHeader("Progma", "No-cache");
        //图形验证码写出,可以写出到文件,也可以写出到流
        try {
            lineCaptcha.write(response.getOutputStream());
            //存储Session
            session.setAttribute(captchaProperties.getSession().getKey(), lineCaptcha.getCode());
            session.setAttribute(captchaProperties.getSession().getDate(), new Date());
            response.getOutputStream().close();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //校验验证码
    @RequestMapping("/check")
    public Boolean check(String inputCode, HttpSession session) {
        //验证码生成的内容,和用户输入的内容进行比较
        if(!StringUtils.hasLength(inputCode)) {
            return false;
        }
        //从Session获取信息
        String saveCode = (String)session.getAttribute(captchaProperties.getSession().getKey());
        Date saveDate = (Date)session.getAttribute(captchaProperties.getSession().getDate());
        if(inputCode.equals(saveCode)) {
        //如果时间超过1分钟,验证码就失效
            if(saveDate != null && (System.currentTimeMillis() - saveDate.getTime()) < session_valid_timeout) {
                return true;
            }
        }
        return false;
    }
}

        代码简单流程: 

           这里使用到了读取配置文件的内容,因为验证码的宽度、长度、Session的key和date字符串也是不变的,所以可以把它们放到配置文件中。先定义它们的值,然后创建对象,把配置文件放到对象中,再使用@Autowired注解,CaptchaController类就可以读取到配置文件中的内容了。

        验证码的界面的设计,由于session里面要存储正确的验证码,如果有多个用户同时登录,就要考虑多线程的,不同的用户返回的验证码也要不同,也符合Session的要求,所以我们使用Session存储用户页面的验证码内容,虽然设置字符串的参数一样,但每个用户在服务器存储的Session是不同的对象,会根据SessionId对应不同用户的Session,而验证码也在Session,刚好也可以传给客户端这边。

        验证码图片是以流的方式传给用户界面,要记得close关掉文件描述符表,不然资源可能会随着请求的增多,把文件描述符表使用完。

        因为我们平时使用的验证码都有时间限制,所以我们设定闲置时间为当前时间减去session设置的时间,因为当验证码向用户传输过去的时候,我们的session才成功创立;我们当前设置时间为1min;

        我们还要设置返回类型,和禁止缓存,因为验证码不能一直都是一样的,为了防止浏览器缓存,就要设置一下。

4.2 前端代码

<!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/get" style="cursor: pointer;" title="看不清?换一张" />
  <input type="button" value="提交" id="checkCaptcha">
</div>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>
<script>

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

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

</script>
</body>

</html>

5. 运行测试

        浏览器访问

验证成功:

验证失败:

ps:本次的内容就到这里了,如果对你有所帮助的话,就请一键三连哦!!!
————————————————

电子签名:上嘉路
 

 

 

  • 12
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
后端代码中添加 "Access-Control-Allow-Origin" 头部字段可以允许指定的域名访问你的后端接口。以下是一些常见的后端语言和框架的示例代码: Node.js(使用 Express 框架): ```javascript const express = require('express'); const app = express(); app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', 'http://example.com'); // 允许 http://example.com 域名访问 res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE'); // 允许的请求方法 res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization'); // 允许的请求头 next(); }); // 其他路由和中间件定义 app.listen(3000, () => { console.log('Server started on port 3000'); }); ``` Python(使用 Flask 框架): ```python from flask import Flask, jsonify app = Flask(__name__) @app.after_request def add_cors_headers(response): response.headers['Access-Control-Allow-Origin'] = 'http://example.com' # 允许 http://example.com 域名访问 response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, DELETE' # 允许的请求方法 response.headers['Access-Control-Allow-Headers'] = 'Content-Type, Authorization' # 允许的请求头 return response # 其他路由和视图函数定义 if __name__ == '__main__': app.run() ``` 这些示例代码会在响应的头部中添加 "Access-Control-Allow-Origin" 字段,指定允许访问的域名。你可以将 `'http://example.com'` 替换为你想要允许访问的域名。同时,你也可以根据需要添加其他的头部字段,如 "Access-Control-Allow-Methods" 和 "Access-Control-Allow-Headers",以控制允许的请求方法和请求头。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值