实现验证码功能

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.kaptcha</groupId>
 <artifactId>kaptcha-spring-boot-starter</artifactId>
 <version>1.0.0-beta-2</version>
</dependency>

生成验证码

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

  • 通过代码来⽣成(参考⽂档: 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>
//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. 校验验证码是否正确: 校验验证码是否正确

接口定义
  1. 生成验证码

    请求

    GET/admin/captcha
    

    响应:图片

  2. 校验验证码是否正确

    请求:/admin/check

    POST /admin/check
    
    captcha=xn8d
    

    captcha:用户输入的验证码

    响应:

    true
    

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

完善前端代码

<!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>

后端代码

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;



    }
}
  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值