SpringBoot整合kaptcha(谷歌验证码工具)实现验证码功能

SpringBoot整合kaptcha(谷歌验证码工具)实现验证码功能

0.Maven

<dependency>
    <groupId>com.google.code</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

1.验证码文本生成器(算术验证码的时候需要)

KaptchaTextCreator 类

package com.safesoft.web.kevin.cacheTest;

import com.google.code.kaptcha.text.impl.DefaultTextCreator;

import java.util.Random;

/**
 * 验证码文本生成器
 *
 * @author 592211009@qq.com
 */
public class KaptchaTextCreator extends DefaultTextCreator
{
    private static final String[] CNUMBERS = "0,1,2,3,4,5,6,7,8,9,10".split(",");

    @Override
    public String getText()
    {
        Integer result = 0;
        Random random = new Random();
        int x = random.nextInt(10);
        int y = random.nextInt(10);
        StringBuilder suChinese = new StringBuilder();
        int randomoperands = (int) Math.round(Math.random() * 2);
        if (randomoperands == 0)
        {
            result = x * y;
            suChinese.append(CNUMBERS[x]);
            suChinese.append("*");
            suChinese.append(CNUMBERS[y]);
        }
        else if (randomoperands == 1)
        {
            if (!(x == 0) && y % x == 0)
            {
                result = y / x;
                suChinese.append(CNUMBERS[y]);
                suChinese.append("/");
                suChinese.append(CNUMBERS[x]);
            }
            else
            {
                result = x + y;
                suChinese.append(CNUMBERS[x]);
                suChinese.append("+");
                suChinese.append(CNUMBERS[y]);
            }
        }
        else if (randomoperands == 2)
        {
            if (x >= y)
            {
                result = x - y;
                suChinese.append(CNUMBERS[x]);
                suChinese.append("-");
                suChinese.append(CNUMBERS[y]);
            }
            else
            {
                result = y - x;
                suChinese.append(CNUMBERS[y]);
                suChinese.append("-");
                suChinese.append(CNUMBERS[x]);
            }
        }
        else
        {
            result = x + y;
            suChinese.append(CNUMBERS[x]);
            suChinese.append("+");
            suChinese.append(CNUMBERS[y]);
        }
        suChinese.append("=?@" + result);
        return suChinese.toString();
    }
}

2.验证码配置

package com.safesoft.web.kevin.cacheTest;

import com.google.code.kaptcha.impl.DefaultKaptcha;
import com.google.code.kaptcha.util.Config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.Properties;

import static com.google.code.kaptcha.Constants.*;
import static com.google.code.kaptcha.Constants.KAPTCHA_BORDER;
import static com.google.code.kaptcha.Constants.KAPTCHA_BORDER_COLOR;
import static com.google.code.kaptcha.Constants.KAPTCHA_IMAGE_HEIGHT;
import static com.google.code.kaptcha.Constants.KAPTCHA_IMAGE_WIDTH;
import static com.google.code.kaptcha.Constants.KAPTCHA_NOISE_COLOR;
import static com.google.code.kaptcha.Constants.KAPTCHA_NOISE_IMPL;
import static com.google.code.kaptcha.Constants.KAPTCHA_OBSCURIFICATOR_IMPL;
import static com.google.code.kaptcha.Constants.KAPTCHA_SESSION_CONFIG_KEY;
import static com.google.code.kaptcha.Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH;
import static com.google.code.kaptcha.Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE;
import static com.google.code.kaptcha.Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR;
import static com.google.code.kaptcha.Constants.KAPTCHA_TEXTPRODUCER_FONT_NAMES;
import static com.google.code.kaptcha.Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE;
import static com.google.code.kaptcha.Constants.KAPTCHA_TEXTPRODUCER_IMPL;

/**
 * 验证码配置
 * 
 * @author 592211009@qq.com
 */
@Configuration
public class CaptchaConfig
{
    @Bean(name = "captchaProducer")
    public DefaultKaptcha getKaptchaBean()
    {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        // 是否有边框 默认为true 我们可以自己设置yes,no
        properties.setProperty(KAPTCHA_BORDER, "yes");
        // 验证码文本字符颜色 默认为Color.BLACK
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "black");
        // 验证码图片宽度 默认为200
        properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
        // 验证码图片高度 默认为50
        properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
        // 验证码文本字符大小 默认为40
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "38");
        // KAPTCHA_SESSION_KEY
        properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCode");
        // 验证码文本字符长度 默认为5
        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "4");
        // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
        // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
        properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }

    @Bean(name = "captchaProducerMath")
    public DefaultKaptcha getKaptchaBeanMath()
    {
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        Properties properties = new Properties();
        // 是否有边框 默认为true 我们可以自己设置yes,no
        properties.setProperty(KAPTCHA_BORDER, "yes");
        // 边框颜色 默认为Color.BLACK
        properties.setProperty(KAPTCHA_BORDER_COLOR, "105,179,90");
        // 验证码文本字符颜色 默认为Color.BLACK
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_COLOR, "blue");
        // 验证码图片宽度 默认为200
        properties.setProperty(KAPTCHA_IMAGE_WIDTH, "160");
        // 验证码图片高度 默认为50
        properties.setProperty(KAPTCHA_IMAGE_HEIGHT, "60");
        // 验证码文本字符大小 默认为40
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_SIZE, "35");
        // KAPTCHA_SESSION_KEY
        properties.setProperty(KAPTCHA_SESSION_CONFIG_KEY, "kaptchaCodeMath");
        // 验证码文本生成器
        properties.setProperty(KAPTCHA_TEXTPRODUCER_IMPL, "com.safesoft.web.kevin.cacheTest.KaptchaTextCreator");
        // 验证码文本字符间距 默认为2
        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_SPACE, "3");
        // 验证码文本字符长度 默认为5
        properties.setProperty(KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, "6");
        // 验证码文本字体样式 默认为new Font("Arial", 1, fontSize), new Font("Courier", 1, fontSize)
        properties.setProperty(KAPTCHA_TEXTPRODUCER_FONT_NAMES, "Arial,Courier");
        // 验证码噪点颜色 默认为Color.BLACK
        properties.setProperty(KAPTCHA_NOISE_COLOR, "white");
        // 干扰实现类
        properties.setProperty(KAPTCHA_NOISE_IMPL, "com.google.code.kaptcha.impl.NoNoise");
        // 图片样式 水纹com.google.code.kaptcha.impl.WaterRipple 鱼眼com.google.code.kaptcha.impl.FishEyeGimpy 阴影com.google.code.kaptcha.impl.ShadowGimpy
        properties.setProperty(KAPTCHA_OBSCURIFICATOR_IMPL, "com.google.code.kaptcha.impl.ShadowGimpy");
        Config config = new Config(properties);
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

3.Kaptcha详细配置表

Kaptcha详细配置表
序号 属性名 描述 示例
1 kaptcha.width 验证码宽度 200
2 kaptcha.height 验证码高度 50
3 kaptcha.border.enabled 是否显示边框 false
4 kaptcha.border.color 边框颜色 black
5 kaptcha.border.thickness 边框厚度 2
6 kaptcha.content.length 验证码文本长度 5
7 kaptcha.content.source 文本源 abcde2345678gfynmnpwx
8 kaptcha.content.space 文本间隔 2
9 kaptcha.font.name 字体名称 Arial
10 kaptcha.font.size 字体大小 40
11 kaptcha.font.color 字体颜色 black
12 kaptcha.background-color.from 背景颜色(开始渐变色) lightGray
13 kaptcha.background-color.to 背景颜色(结束渐变色 white

4.就可以使用了-举个例子(控制层)

eg:

/**
 * [验证码控制层]
 *
 * @author Kevin.Wan
 * @date 2023/6/16
 **/
@RestController
public class CaptchaController {
    @Resource(name = "captchaProducer")
    private Producer captchaProducer;

    @Resource(name = "captchaProducerMath")
    private Producer captchaProducerMath;


    /**
     * 生成验证码
     */
    @GetMapping("/captchaImage")
    public Rest<ValidateCodeVO> getCode(HttpServletResponse response) throws IOException
    {
        ValidateCodeVO validateCodeVO = new ValidateCodeVO();
        //这一步获取是否开启了验证码功能
        boolean captchaOnOff = true;
        if (!captchaOnOff)
        {
            return RestBody.okData(validateCodeVO);
        }

        // 保存验证码信息
        String uuid = UUID.randomUUID().toString();
        //用于缓存的key
        String verifyKey = "captcha_codes:"+ uuid;

        String capStr = null, code = null;
        BufferedImage image = null;

        // 生成验证码
        //先获取验证码类型  在配置文件中获取  这里先直接定义了
        String captchaType = "char";  //math 数组计算(几加几等于几) char 字符验证(就是认字母)
        if ("math".equals(captchaType))
        {
            String capText = captchaProducerMath.createText();
            capStr = capText.substring(0, capText.lastIndexOf("@"));
            code = capText.substring(capText.lastIndexOf("@") + 1);
            image = captchaProducerMath.createImage(capStr);
        }
        else if ("char".equals(captchaType))
        {
            capStr = code = captchaProducer.createText();
            image = captchaProducer.createImage(capStr);
        }

        //redisCache.setCacheObject(verifyKey, code, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        // 转换流信息写出
        FastByteArrayOutputStream os = new FastByteArrayOutputStream();
        try
        {
            ImageIO.write(image, "jpg", os);
        }
        catch (IOException e)
        {
            return (Rest<ValidateCodeVO>) RestBody.failure(8888,e.getMessage());
        }


        validateCodeVO.setUuid(uuid);
        validateCodeVO.setDataBase64(Base64.encode(os.toByteArray()));
        return RestBody.okData(validateCodeVO);
    }

}

5.返回的信息

{
    "code": 200,
    "data": {
        "uuid": "31450b4a-5600-4434-a9e5-8b64fa7280b4",
        "dataBase64": "/9j/4AAQSkZJRgABAgAAAQABAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc0ZYLy3kt5GjhlDBXUqSMyEZwfQ0Af/Z******************************"
    },
    "msg": "ok",
    "identifier": "success"
}

6.前端展示

vue2:

    <div class="login-code">
      <img :src="codeUrl" @click="getCode" class="login-code-img"/>
    </div>

这里展示的url 一定一定要加 data:image/gif;base64,

 methods: {
    getCode() {
          this.$axios({
			       	  method:'GET',
			      	  url:"/captchaImage",
				        headers: {
                  "Content-Type": "application/json"
                }
            }).then(res=>{
              this.codeUrl = "data:image/gif;base64," + res.data.img;
            })
    },

vue3:

          <div class="propName">验证码</div>
          <el-form-item prop="validateCode">
            <div class="verification">
              <div class="show-box" @click="getValid2">
                <el-image style="width: 100%; height: 100%" fit="none" :src="validCodeBase64Img" />
              </div>
              <el-input v-model="form.validateCode" :maxlength="10" :prefix-icon="ElementPlus" class="input_box" />
            </div>
          </el-form-item>

带校验了这个

最主要:

const getValid2 = () => {
  getValidCode2().then((res) => {
    form.uuid = res.data.uuid;
    validCodeBase64Img.value = "data:image/gif;base64,"+res.data.dataBase64;
  });
};
getValid2()   //系统进来就触发这个方法
// 验证码接口
export const getValidCode2 = (): Promise<any> => {
  return AxiosRequest({
    method: 'get',
    url: '/captchaImage',
  })
}

7.效果

Valid2 = () => {
getValidCode2().then((res) => {
form.uuid = res.data.uuid;
validCodeBase64Img.value = “data:image/gif;base64,”+res.data.dataBase64;
});
};
getValid2() //系统进来就触发这个方法


```js
// 验证码接口
export const getValidCode2 = (): Promise<any> => {
  return AxiosRequest({
    method: 'get',
    url: '/captchaImage',
  })
}

7.效果

当String captchaType = “math”;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-m1C2EKPp-1686900951222)(C:\Users\kevin.wan\Desktop\学到的东西总结图片\验证码效果.png)]
当String captchaType = “char”;在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值