SpringBoot整合kisso+Redis实现图片验证码功能

baomidou/kisso的GitHub地址:https://github.com/baomidou/kisso

kisso官方文档的验证码教程地址:http://doc.aizuda.com/pages/9xd006/


pom文件加入依赖

        <!--图片验证码依赖-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>kisso</artifactId>
            <version>3.8.1</version>
        </dependency>

因为要用Redis缓存验证,写个ICaptchaStore 接口的类RedisCaptchaStore,我放工具类文件夹里了。

这里直接注入RedisTemplate会空指针异常,用@PostConstruct在项目启动的时候执行注入下。

package com.zeromemos.utils;

import com.baomidou.kisso.captcha.ICaptchaStore;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.util.concurrent.TimeUnit;

@Component
public class RedisCaptchaStore implements ICaptchaStore {

    @Autowired
    private RedisTemplate redisTemplate;

    public static RedisTemplate redis;

    //在项目启动的时候执行该方法,避免RedisTemplate注入失败
    @PostConstruct
    public void getRedisTemplate() {
        redis = this.redisTemplate;
    }

    @Override
    public String get(String s) {
        return (String) redis.opsForValue().get(s);
    }

    @Override
    public boolean put(String s, String s1) {
        redis.opsForValue().set(s, s1, 10, TimeUnit.SECONDS);//这里验证码10秒钟就失效了
        return true;
    }
}

Config配置类里加个配置,设置验证码配置

@Bean
    public ImageCaptcha imageCaptcha(){
        ImageCaptcha imageCaptcha = ImageCaptcha.getInstance();
        // 干扰量 5
        imageCaptcha.setInterfere(5);
        // 验证码内容长度 4 位
        imageCaptcha.setLength(4);
        // Gif 验证码
        // imageCaptcha.setGif(true);
        // 验证码存储处理类,默认存在在 session 实现类 CaptchaStoreSession 仅适用单机
        // 分布式可以采用 Redis 处理,例如 RedisCaptchaStore 实现 ICaptchaStore 接口
        imageCaptcha.setCaptchaStore(new RedisCaptchaStore());
        return imageCaptcha;
    }

写Controller测试

@RestController
@RequestMapping("/captcha")
public class CaptchaController {

    @Autowired
    private HttpServletRequest request;

    @Autowired(required = false)
    private HttpServletResponse response;

    @Autowired
    private ICaptcha captcha;

    // 生成验证,例如:http://localhost:9001/captcha/image?ticket=123456
    @GetMapping("/image")
    public void image(String ticket) {
        try {
            // 验证码信息存放在缓存中,key = ticket 、 value = 验证码文本内容
            captcha.generate(request, response.getOutputStream(), ticket);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 校验图片验证码
    @PostMapping("/verification")
    public boolean verification(String ticket, String code) {
        // ticket 为生成验证码的票据, code 为图片验证码文本内容
        return captcha.verification(request, ticket, code);
    }
}

获取,验证,和超过设置时间的验证结果


补充:如果配置类Config里直接用@Autowired注入RedisTemplate对象去使用


RedisCaptchaStore里直接使用@Autowired注入RedisTemplate对象不会出现空指针异常