当前位置: 代码网 > it编程>编程语言>Java > SpringBoot3整合Hutool-captcha实现图形验证码

SpringBoot3整合Hutool-captcha实现图形验证码

2024年11月29日 Java 我要评论
验证码需求分析:1. 生成验证码,点击图片可进行刷新2. 输入验证码,点击提交,验证用户输入验证码是否正确项目创建首先创建项目这里使用的spring boot 3 + jdk17,并引入相关依赖pom

验证码需求分析:

1. 生成验证码,点击图片可进行刷新
2. 输入验证码,点击提交,验证用户输入验证码是否正确

项目创建

首先创建项目这里使用的spring boot 3 + jdk17,并引入相关依赖

pom.xml

<properties>
        <java.version>17</java.version>

        <hutool.version>5.8.26</hutool.version>
    </properties>
    <dependencies>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-web</artifactid>
        </dependency>
        <dependency>
            <groupid>org.projectlombok</groupid>
            <artifactid>lombok</artifactid>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-starter-test</artifactid>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupid>org.springframework.boot</groupid>
            <artifactid>spring-boot-devtools</artifactid>
            <optional>true</optional>
        </dependency>
        <dependency>
            <groupid>cn.hutool</groupid>
            <artifactid>hutool-captcha</artifactid>
        </dependency>
    </dependencies>
    <dependencymanagement>
        <dependencies>
            <dependency>
                <groupid>cn.hutool</groupid>
                <artifactid>hutool-bom</artifactid>
                <version>${hutool.version}</version>
                <type>pom</type>
                <!-- 注意这里是import -->
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencymanagement>

import方式的使用说明

如果你想像spring-boot一样引入hutool,再由子模块决定用到哪些模块,你可以在父模块中加入:

<dependencymanagement>
    <dependencies>
        <dependency>
            <groupid>cn.hutool</groupid>
            <artifactid>hutool-bom</artifactid>
            <version>${hutool.version}</version>
            <type>pom</type>
            <!-- 注意这里是import -->
            <scope>import</scope>
        </dependency>
    </dependencies>
</dependencymanagement>

在子模块中就可以引入自己需要的模块了:

<dependency>
    <groupid>cn.hutool</groupid>
    <artifactid>hutool-captcha</artifactid>
</dependency>

使用import的方式,只会引入hutool-bom内的dependencymanagement的配置,其它配置在这个引用方式下完全不起作用。

exclude方式

如果你引入的模块比较多,但是某几个模块没用,你可以:

<dependencies>
    <dependency>
        <groupid>cn.hutool</groupid>
        <artifactid>hutool-bom</artifactid>
        <version>${hutool.version}</version>
        <!-- 加不加这句都能跑,区别只有是否告警  -->
        <type>pom</type>
        <exclusions>
            <exclusion>
                    <groupid>cn.hutool</groupid>
                    <artifactid>hutool-system</artifactid>
            </exclusion>
        </exclusions>
    </dependency>
</dependencies>

这个配置会传递依赖hutool-bom内所有dependencies的内容,当前hutool-bom内的dependencies全部设置了version,就意味着在maven resolve的时候hutool-bom内就算存在dependencymanagement也不会产生任何作用。

定义接口:

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

接口定义

1.  生成验证码
[url]
get /captcha/getcaptcha
[请求参数]
[响应]
{
    "uuid": "fc2b40825f20470bb4f5d9868b33856f",
    "img": "data:image/png;base64,issaxxxxxxxxgg=="
}

uuid 是为了方便在真实项目使用中做区分
2. 校验验证码是否正确
[url]
post /captcha/check
[请求参数]
{"uuid":"43b4b30bf1134e9f8430507b7babd620","code":""}
[响应]
{
   true
}

根据用户输入的验证码,校验验证码是否正确,校验成功,返回true;校验失败,返回false

定义 captchacontroller

@slf4j
@restcontroller
@requestmapping("/captcha")
@allargsconstructor
public class captchacontroller {

    private final syscaptchaservice syscaptchaservice;

    /**
     * 生成验证码
     */
    @getmapping("/getcaptcha")
    public captcharesult getcaptcha(httpsession session) {
        return syscaptchaservice.getcaptcha(session);
    }

    /**
     * 验证码校验
     *
     * @param param 验证码参数
     */
    @postmapping("/check")
    public boolean checkcaptcha(@requestbody captchavalidateparam param, httpsession session) {
        string uuid = param.getuuid();
        string captcha = param.getcode();
        if (strutil.isempty(uuid) || strutil.isempty(captcha)) {
            log.error("验证码参数不能为空");
            return false;
        }
        log.info("接收到验证码: uuid:{}, 验证码:{}", uuid, captcha);
        // 参数校验
        return syscaptchaservice.validate(uuid, captcha, session);
    }
}

由于当用户输入验证码时,我们需要进行校验,因此,我们需要对生成的验证码进行存储,同时,需要存储验证码的生成时间,以便判断验证码是否超时

public class constants {
    public static final string captcha_code = "code";
    public static final string captcha_uuid = "uuid";
}
  • syscaptchaservice
public interface syscaptchaservice {

    /**
     * 获取验证码
     *
     * @param session
     * @return
     */
    captcharesult getcaptcha(httpsession session);

    /**
     * 验证码效验
     *
     * @param uuid
     * @param code
     * @param session
     * @return
     */
    boolean validate(string uuid, string code, httpsession session);
}

  • syscaptchaserviceimpl
@service
@requiredargsconstructor
@slf4j
public class syscaptchaserviceimpl implements syscaptchaservice {

    private final captchaproperties captchaproperties;
    private final codegenerator codegenerator;
    private final font captchafont;


    @override
    public captcharesult getcaptcha(httpsession session) {


        string captchatype = captchaproperties.gettype();
        int width = captchaproperties.getwidth();
        int height = captchaproperties.getheight();
        int interferecount = captchaproperties.getinterferecount();
        int codelength = captchaproperties.getcode().getlength();

        abstractcaptcha captcha;
        if (captchatypeenums.circle.name().equalsignorecase(captchatype)) {
            captcha = captchautil.createcirclecaptcha(width, height, codelength, interferecount);
        } else if (captchatypeenums.gif.name().equalsignorecase(captchatype)) {
            captcha = captchautil.creategifcaptcha(width, height, codelength);
        } else if (captchatypeenums.line.name().equalsignorecase(captchatype)) {
            captcha = captchautil.createlinecaptcha(width, height, codelength, interferecount);
        } else if (captchatypeenums.shear.name().equalsignorecase(captchatype)) {
            captcha = captchautil.createshearcaptcha(width, height, codelength, interferecount);
        } else {
            throw new illegalargumentexception("invalid captcha type: " + captchatype);
        }
        captcha.setgenerator(codegenerator);
        captcha.settextalpha(captchaproperties.gettextalpha());
        captcha.setfont(captchafont);

        string code = captcha.getcode();
        string imagebase64data = captcha.getimagebase64data();

        // 验证码文本缓存至redis,用于登录校验
        string uuid = idutil.fastsimpleuuid();

        session.setattribute(constants.captcha_code, code);
        session.setattribute(constants.captcha_uuid, uuid);

        return captcharesult.builder().img(imagebase64data).uuid(uuid).build();
    }

    @override
    public boolean validate(string uuid, string code, httpsession session) {
        // session中获取验证码
        string captchacode = (string) session.getattribute(constants.captcha_code);
        return codegenerator.verify(captchacode, code);
    }

将用户输入的验证码与存储在 session 中的验证码进行对比,判断其是否相同,若相同且在1min内,则验证成功

前端代码

<!doctype html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <title>title</title>
    <style>
        #app {
            font-family: avenir, helvetica, arial, sans-serif;
            -webkit-font-smoothing: antialiased;
            -moz-osx-font-smoothing: grayscale;
            text-align: center;
            color: #2c3e50;
            margin-top: 60px;
        }

        #inputcaptcha {
            height: 30px;
            vertical-align: middle;
        }

        #verificationcodeimg {
            vertical-align: middle;
        }

        #checkcaptcha {
            height: 40px;
            width: 100px;
            border: 1px solid #000;
            border-radius: 5px;
            margin-left: 10px;
            vertical-align: middle;
        }
    </style>
</head>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.4/jquery.min.js"></script>

<body>
<div id="app">
    <h1>{{ message }}</h1>
    <input type="text" v-model="inputcaptcha" id="inputcaptcha">
    <img id="verificationcodeimg" :src="captchadata.img" alt="验证码" @click="refreshcaptcha" title="看不清?换一张"/>
    <input type="button" value="提交" id="checkcaptcha" @click="checkcaptcha">
</div>

<script type="module">
    import {createapp, ref, onmounted} from 'https://unpkg.com/vue@3/dist/vue.esm-browser.js'

    createapp({
        setup() {
            const message = ref('验证码校验')
            const inputcaptcha = ref('')
            const captchadata = ref({
                img: '',
                uuid: ''
            })

            const refreshcaptcha = () => {
                $.ajax({
                    url: '/captcha/getcaptcha',
                    type: 'get',
                    success: function (data) {
                        captchadata.value = data
                    }
                })
            }

            const checkcaptcha = () => {
                const  datafrom = {
                    uuid: captchadata.value.uuid,
                    code: inputcaptcha.value
                }
                $.ajax({
                    url: '/captcha/check',
                    type: 'post',
                    headers: {
                        'content-type': 'application/json'
                    },
                    data: json.stringify(datafrom),
                    success: function (data) {
                        if (data) {
                            alert('验证码正确')
                            refreshcaptcha()
                        } else {
                            alert('验证码错误')
                            refreshcaptcha()
                        }
                    }
                })
            }

            // 页面加载完成后,刷新验证码
            onmounted(() => {
                refreshcaptcha()
            })

            return {
                message,
                captchadata,
                inputcaptcha,
                refreshcaptcha,
                checkcaptcha
            }
        }
    }).mount('#app')
</script>
</body>
</html>

验证成功:

验证失败:

为让验证码有多样性,这里将验证的生成放入了application.yml配置文件中,内容如下:

# 验证码配置
captcha:
  # 验证码类型 circle-圆圈干扰验证码|gif-gif验证码|line-干扰线验证码|shear-扭曲干扰验证码
  type: circle
  # 验证码宽度
  width: 130
  # 验证码高度
  height: 48
  # 验证码干扰元素个数
  interfere-count: 2
  # 文本透明度(0.0-1.0)
  text-alpha: 0.8
  # 验证码字符配置
  code:
    # 验证码字符类型 math-算术|random-随机字符
    type: math
    # 验证码字符长度,type=算术时,表示运算位数(1:个位数运算 2:十位数运算);type=随机字符时,表示字符个数
    length: 1
  # 验证码字体
  font:
    # 字体名称 dialog|dialoginput|monospaced|serif|sansserif
    name: sansserif
    # 字体样式 0-普通|1-粗体|2-斜体
    weight: 1
    # 字体大小
    size: 20
  # 验证码有效期(秒)
  expire-seconds: 120

以上就是springboot3整合hutool-captcha实现图形验证码的详细内容,更多关于springboot3 hutool-captcha验证码的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com