• 实现验证码功能


    Kaptcha

    介绍

    Kaptcha 是Google的⼀个⾼度可配置的实⽤验证码⽣成⼯具

    https://code.google.com/archive/p/kaptcha

    ⽹上有很多⼈甚⾄公司基于Google的kaptcha进⾏了⼆次开发. 我们选择⼀个直接适配SpringBoot的开源项⽬

    oopsguy/kaptcha-spring-boot: Kaptcha Spring Boot Starter help you use Google Kaptcha with Spring Boot easier. 一个简单封装了 Kaptcha 验证码库的 Spring Boot Starter (github.com)

    插件使用介绍

    基于GitHub项目来做介绍

    原理

    验证码可以客⼾端⽣成, 也可以服务器⽣成. 对于普通的字符验证码, 后端通常分两部分.

    ⼀是⽣成验证码内容, 根据验证码内容和⼲扰项等, ⽣成图⽚, 返回给客⼾端

    ⼆是把验证码内容存储起来, 校验时取出来进⾏对⽐.

    kaptcha插件选择把验证码存储在Session⾥.

    引入依赖

    <dependency>
     <groupId>com.oopsguy.kaptchagroupId>
     <artifactId>kaptcha-spring-boot-starterartifactId>
     <version>1.0.0-beta-2version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5

    生成验证码

    该插件提供了两种⽅式⽣成验证码

    • 通过代码来⽣成(参考⽂档: https://github.com/oopsguy/kaptcha-spring-boot/blob/master/README_zh-CN.md, 不再介绍)

    • 仅通过配置⽂件来⽣成验证码(推荐)

    部分详细配置

    配置项配置说明默认值
    border设置验证码边框的颜色“255,255,255,255”
    textProducerCharLength设置生成验证码的字符长度4
    textProducerCharSpace设置生成验证码时字符之间的间距5
    imageWidth设置验证码图片的宽度200
    imageHeight设置验证码图片的高度50
    noiseColor设置噪点的颜色“255,255,255,255”
    fontColor设置字体颜色“0,0,0,255”
    fontNames设置字体的名称,可以指定多个字体Arial, Courier
    textProducerImpl设置生成验证码文本的实现类默认实现类
    backgroundProducerImpl设置生成验证码背景的实现类默认实现类
    noiseProducerImpl设置生成验证码噪点的实现类默认实现类
    wordImpl设置生成验证码字符的实现类默认实现类
    obscurificatorImpl设置字符模糊处理的实现类默认实现类
    sessionKey设置存储验证码信息的 Session 键默认值
    sessionDate设置存储验证码创建时间的 Session 键默认值
    width设置验证码图片的宽度(同 imageWidth)200
    height设置验证码图片的高度(同 imageHeight)50

    验证码小项目

    初始化前端代码

    // 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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    //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="/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>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45

    约定前后端交互接口

    需求分析

    后端需要提供两个服务

    1. ⽣成验证码, 并返回验证码

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

    接口定义
    1. 生成验证码

      请求

      GET/admin/captcha
      
      • 1

      响应:图片

    2. 校验验证码是否正确

      请求:/admin/check

      POST /admin/check
      
      captcha=xn8d
      
      • 1
      • 2
      • 3

      captcha:用户输入的验证码

      响应:

      true
      
      • 1

      根据用户输入的验证码,校验验证码是否正确

    完善前端代码

    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 () {
                    $.ajax({
                        type:"get",
                        url:"/admin/check",
                        data:{
                          inputCaptcha:$("#inputCaptcha").val()
                        },
                        success:function (result){
                            if (result){
                                // 页面跳转
                                location.href="success.html"
                            }else {
                                alert("验证码失败,请重试");
                            }
                        }
                    });
                });
    
            script>
        body>
    
    html>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    后端代码

    package org.haobin.kaptcha;
    
    import org.springframework.util.StringUtils;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    import javax.servlet.http.HttpSession;
    import java.util.Date;
    
    @RestController
    @RequestMapping("/admin")
    public class KaptchaController {
        public static final String KAPTCHA_SESSION_KEY = "KAPTCHA_SESSION_KEY";
        public static final String KAPTCHA_SESSION_DATE = "KAPTCHA_SESSION_DATE";
        public static final long TIME_OUT = 60 * 1000; // 1min 毫秒
    
        /**
         * 校验验证码是否正确
         *
         * @param inputCaptcha 用户输入的验证码
         * @return
         */
        @RequestMapping("/check")
        public boolean check(String inputCaptcha, HttpSession session) {
            // 1. 判断输入的验证码是否为空
            if (!StringUtils.hasLength(inputCaptcha)) {
                return false;
            }
            // 2. 获取生成的验证码
            // 正确的验证码(生成验证码)
            // 3. 比对 生成的验证码和输入的验证码是否一致
            // 4. 确认验证码是否过期
            String saveCaptcha = (String) session.getAttribute(KAPTCHA_SESSION_KEY);
            Date saveCaptchaDate = (Date) session.getAttribute(KAPTCHA_SESSION_DATE);
            // 不区分大小写
            if (inputCaptcha.equalsIgnoreCase(saveCaptcha)) {
                if (saveCaptchaDate != null || System.currentTimeMillis() - saveCaptchaDate.getTime() < TIME_OUT) {
                    return true;
                }
            }
            return false;
    
    
    
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
  • 相关阅读:
    每日一题:无感刷新页面(附可运行的前后端源码,前端vue,后端node)
    Python-Pandas库中的交叉表
    React过渡动画
    02 - 雷达探测能力——基本雷达方程
    新媒体运营-----短视频运营-----PR视频剪辑----字幕
    引入隔离率与潜伏人员的SIR模型附matlab代码
    阿里云oss存储文件上传功能实现(保姆级教程)
    Python解析参数的三种方法
    云计算【第一阶段(14)】Linux的目录和结构
    论文相关知识:扁平化设计
  • 原文地址:https://blog.csdn.net/m0_73075027/article/details/136304946