java-Kaptcha生成验证码图片(五分钟学会)

验证码的作用是防止恶意破解密码、刷票、论坛灌水、刷页等。
如下是一个实际例子:


image.png

而Kaptcha则是生成这样的验证码图片的一个功能强大的工具包。
然后开始说这个Kaptcha要怎么使用。

导包


    com.github.axet
    kaptcha
    0.0.9

添加配置

package io.renren.config;

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;


/**
 * 生成验证码配置
 *
 * @author Mark [email protected]
 */
@Configuration
public class KaptchaConfig {

    @Bean
    public DefaultKaptcha producer() {
        Properties properties = new Properties();
        properties.put("kaptcha.border", "no");
        properties.put("kaptcha.textproducer.font.color", "black");
        properties.put("kaptcha.textproducer.char.space", "6");
        properties.put("kaptcha.textproducer.font.names", "Arial,Courier,cmr10,宋体,楷体,微软雅黑");
        Config config = new Config(properties);
        DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
        defaultKaptcha.setConfig(config);
        return defaultKaptcha;
    }
}

然后上面的几个配置自己看着写。这个kaptcha有多种配置可以改的,我贴出来:


kaptcha可选参数

可选参数2

反正我用起来也没那么麻烦,其实默认配置差不多就满足了,自己看心意调吧。

在接口中使用

以上两步配置就完了,接下来该使用了。
其实就是把它配置成一个可以前端访问的接口了。

存session中

    @Autowired
    private Producer producer;
    
    @GetMapping("kaptcha.jpg")
    public void kaptcha(HttpServletResponse response,HttpServletRequest request) throws ServletException,IOException{
        response.setHeader("Cache-Control", "no-store,no-cache");
        response.setContentType("image/jpeg");
        //生成文字验证码
        String text=producer.createText();
        //生成图片验证码
        BufferedImage image=producer.createImage(text);
        //保存验证码到session
        request.getSession().setAttribute(Constants.KAPTCHA_SESSION_KEY, text);
        ServletOutputStream out=response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        //用到IO工具包控制开关
        IOUtils.closeQuietly(out);
        
    }

存数据库

存session就不多说了,但是我使用的时候是存数据库的,个人感觉存数据库可以灵活设置过期时间。(好吧,我承认这个做法是当时没想到session)。反正现在是实现了,所以也记录下来吧。
因为存数据库所以肯定要先建表:


表结构

如图,很简单的表结构:uuid是主键,code是验证码。expire_time是过期时间。
然后每次生成验证码,需要一个参数(说是uuid其实用的时候就是一个id的作用)。会将这个uuid当做表的主键,然后code和过期时间一起存到数据库。
在登录的时候先做校验,判断这个uuid的code和输入的验证码是否一样,是的话验证成功,并且删除这条记录。不是的话返回验证码错误。
大概逻辑就是这样,我一步步贴代码:
这个是将验证码保存到数据库和校验验证码的两个方法

    @Autowired
    private Producer producer;
    
    /**
     * 生成验证码并且将这条记录保存到数据库
     */
    @Override
    public BufferedImage getCaptcha(String uuid) {
        if(StringUtils.isBlank(uuid)){
            throw new RRException("uuid不能为空");
        }
        //生成文字验证码
        String code = producer.createText();
        //这里是生成实体,然后存入数据库,看逻辑就行,别原封不动用代码
        SysCaptchaEntity captchaEntity = new SysCaptchaEntity();
        captchaEntity.setUuid(uuid);
        captchaEntity.setCode(code);
        //3分钟后过期.这个用到了自己封装的日期处理方法
        captchaEntity.setExpireTime(DateUtils.addDateMinutes(new Date(), 3));
        this.save(captchaEntity);
        return producer.createImage(code);
    }
    
    
    /**
     * 验证验证码是否正确
     */
    @Override
    public boolean validate(String uuid, String code) {
        SysCaptchaEntity captchaEntity = this.getOne(new QueryWrapper().eq("uuid", uuid));
        if(captchaEntity == null){
            return false;
        }

        //删除验证码
        this.removeById(uuid);

        if(captchaEntity.getCode().equalsIgnoreCase(code) && captchaEntity.getExpireTime().getTime() >= System.currentTimeMillis()){
            return true;
        }

        return false;
    }

这个是正式调用生成验证码的方法:

    /**
     * 验证码
     */
    @ApiOperation("获取验证码")
    @RequestMapping("kaptcha.jpg")
    public void kaptcha(HttpServletResponse response, @ApiParam(name="uuid",value="随机字符串") String uuid)throws IOException {
        response.setHeader("Cache-Control", "no-store, no-cache");
        response.setContentType("image/jpeg");

        //获取图片验证码
        BufferedImage image = sysCaptchaService.getCaptcha(uuid);

        ServletOutputStream out = response.getOutputStream();
        ImageIO.write(image, "jpg", out);
        IOUtils.closeQuietly(out);
    }

这个是在登录的时候验证验证码的两行代码:

boolean captcha = sysCaptchaService.validate(form.getUuid(), form.getCaptcha());
        if(!captcha){
            return R.error("验证码不正确");
        }

至此,这个生成验证码的功能完成了,顺便附上截图:


postman自测

网页测试

本篇笔记就到这里,如果稍微帮到你了记得点个喜欢点个关注。也祝大家工作顺顺利利,生活愉快!

你可能感兴趣的:(java-Kaptcha生成验证码图片(五分钟学会))