SpringBoot配置Kaptcha验证码

作者: SevenLin1993 | 来源:发表于2019-07-29 21:45 被阅读8次

    SpringBoot配置Kaptcha验证码

    简介

    验证码的作用其实就是通过人为操作来防止暴力破解、机器人等。

    本文通过SprinBoot +Kaptcha实现图片验证码生成功能,验证码的保存一般使用缓存,可以选择使用Redis或者一些Java的缓存实现(例如,EhCache,guava cache等),如果分布式系统请使用Redis,这里简单Demo使用EhCache实现验证码缓存,具体实现如下:

    Maven依赖

    可以通过Spring Initializr实现初始化:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    
    <dependency>
        <groupId>com.github.axet</groupId>
        <artifactId>kaptcha</artifactId>
        <version>0.0.9</version>
    </dependency>
    
    <dependency>
        <groupId>org.apache.commons</groupId>
        <artifactId>commons-lang3</artifactId>
    </dependency>
    
    <dependency>
        <groupId>net.sf.ehcache</groupId>
        <artifactId>ehcache</artifactId>
    </dependency>
    

    启动缓存

    @Configuration
    @EnableCaching
    public class EhCacheConfiguration {}
    

    配置验证码图片生成

    @Configuration
    public class KaptchaConfiguration {
    
        /**
         * 默认生成图形验证码宽度
         */
        private static final String DEFAULT_IMAGE_WIDTH = "100";
    
        /**
         * 默认生成图像验证码高度
         */
        private static final String DEFAULT_IMAGE_HEIGHT = "40";
    
        /**
         * 默认生成图形验证码长度
         */
        private static final String DEFAULT_IMAGE_LENGTH = "4";
    
        /**
         * 颜色,合法值: r,g,b (and optional alpha) 或者 white,black,blue.
         */
        private static final String DEFAULT_COLOR_FONT = "black";
    
        /**
         * 图片边框
         */
        private static final String DEFAULT_IMAGE_BORDER = "no";
    
        /**
         * 默认图片间隔
         */
        private static final String DEFAULT_CHAR_SPACE = "5";
    
        /**
         * 验证码文字大小
         */
        private static final String DEFAULT_IMAGE_FONT_SIZE = "30";
    
        @Bean
        public DefaultKaptcha producer() {
            Properties properties = new Properties();
            properties.put(Constants.KAPTCHA_BORDER, DEFAULT_IMAGE_BORDER);
            properties.put(Constants.KAPTCHA_TEXTPRODUCER_FONT_COLOR, DEFAULT_COLOR_FONT);
            properties.put(Constants.KAPTCHA_TEXTPRODUCER_CHAR_SPACE, DEFAULT_CHAR_SPACE);
            properties.put(Constants.KAPTCHA_IMAGE_WIDTH, DEFAULT_IMAGE_WIDTH);
            properties.put(Constants.KAPTCHA_IMAGE_HEIGHT, DEFAULT_IMAGE_HEIGHT);
            properties.put(Constants.KAPTCHA_TEXTPRODUCER_FONT_SIZE, DEFAULT_IMAGE_FONT_SIZE);
            properties.put(Constants.KAPTCHA_TEXTPRODUCER_CHAR_LENGTH, DEFAULT_IMAGE_LENGTH);
            Config config = new Config(properties);
            DefaultKaptcha defaultKaptcha = new DefaultKaptcha();
            defaultKaptcha.setConfig(config);
            return defaultKaptcha;
        }
    }
    
    

    配置Ehcache

    ehcache.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
             updateCheck="false">
    
        <diskStore path="java.io.tmpdir"/>
    
        <defaultCache
                eternal="false"
                maxElementsInMemory="10000"
                overflowToDisk="true"
                diskPersistent="false"
                timeToIdleSeconds="120"
                timeToLiveSeconds="120"
                diskExpiryThreadIntervalSeconds="120"
                memoryStoreEvictionPolicy="LRU"/>
    
        <cache
                name="kaptcha"
                eternal="false"
                maxElementsInMemory="1000"
                overflowToDisk="false"
                diskPersistent="false"
                timeToIdleSeconds="120"
                timeToLiveSeconds="180"
                memoryStoreEvictionPolicy="LRU"/>
    
    </ehcache>
    

    SpringBoot application.properties 配置

    spring.cache.type=ehcache
    spring.cache.ehcache.config=classpath:/ehcache.xml
    

    测试

    • 启动一个Controller
    @Controller
    @RequestMapping("/api/v1/kaptcha")
    @Slf4j
    public class KaptchaController {
    
        @Autowired
        private Producer producer;
    
        @Autowired
        private CacheManager cacheManager;
    
        @GetMapping("/code")
        public void generation(HttpServletResponse response) {
    
            String text = RandomStringUtils.randomAlphanumeric(4);
    
            log.info("生成验证码:{}", text);
    
            BufferedImage image = producer.createImage(text);
    
            //缓存验证码
            cacheManager.getCache("kaptcha").put(text, text);
    
            //set content type
            response.setContentType(MediaType.IMAGE_JPEG.getType());
            try {
                FastByteArrayOutputStream os = new FastByteArrayOutputStream();
                ImageIO.write(image, "jpeg", os);
                os.writeTo(response.getOutputStream());
            } catch (IOException e) {
                log.error("验证码处理失败:{}", e.getMessage(), e);
                throw new RuntimeException("验证码获取失败", e);
            }
    
        }
    }
    
    • 启动工程
    @SpringBootApplication
    public class KaptchaDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(KaptchaDemoApplication.class, args);
        }
    }
    
    
    • 运行,浏览器访问:http://localhost:8080/api/v1/kaptcha/code

    总结

    • 使用图片验证码一般会设置过期时间
    • 大部分验证码都是大小写忽略(Demo中是大小写敏感)
    • 分布式环境缓存需要统一,例如使用Redis
    • 结合Spring Security的时候记得把验证码的URL权限放开

    相关文章

      网友评论

        本文标题:SpringBoot配置Kaptcha验证码

        本文链接:https://www.haomeiwen.com/subject/kazirctx.html