张坤的个人博客

  • 首页
  • 分类
  • 标签
  • 日志

  • 搜索
Lombok Dubbo Jenkins RabbitMQ Zookeeper IDEA Logstash Kibana ELK NIO Netty Spring Cloud Golang DataX Elasticsearch React Native Mysql H2 Socket Spring Boot Kafka Mybatis Sqlmap Vue Postgresql Docker Vert.x Flutter Flink Redis

登录验证码开发记录

发表于 2020-05-29 | 分类于 默认分类 | 0 | 阅读次数 59

登录验证码开发记录

后台使用了Controller层选用了SpringMvc,验证码存储在Ehcache中并设置自动过期时间为1分钟,key值使用sessionId,验证码生成使用了kaptcha插件。

需求分析:

  1. 前台需要生成一个4位数的验证码图片
  2. 提交之后由后台判断验证码是否输入正确
  3. 验证码有效期为1分钟

思路分析:

  1. 在后台生成一个4位数的随机数字作为验证码值存入ehcache中,设置ehcache的过期时间为1分钟,key值为sessionId。将验证码值用kaptcha插件生成验证码图片,并返回到前台
  2. 用户输入验证码登录之后,在登录接口从ehcache根据sessionId获取验证码,如果为null,则表示验证码已过期,如果不等于前台传过来的验证码,则返回验证码错误,否则登录成功

前台代码:

<img class="authCode" ref="authCode" src="/login/authcode" @click.stop="getAuthCode" title="点击切换验证码">
<script>
getAuthCode: function () {
                    $(this.$refs.authCode).attr('src', '/login/authcode?' + Math.floor(Math.random() * 1000000));
                }
</script>

当点击img标签时,重新获取验证码,后面跟上随机数防止页面缓存

后端获取验证码接口

@Autowired
private Producer kaptchaProducer;

@Autowired
private CacheManager cacheManager

@RequestMapping("/authcode")
    public void authCode(HttpServletRequest request, HttpServletResponse response) {
        response.setContentType("image/jpeg");
        String capText = kaptchaProducer.createText();
        Cache cache = cacheManager.getCache("authCode");
        Element element = new Element(request.getRequestedSessionId(), capText);
        cache.put(element);
        BufferedImage bi = kaptchaProducer.createImage(capText);
        ServletOutputStream out = null;
        try {
            out = response.getOutputStream();
            out.flush();
            ImageIO.write(bi, "jpg", out);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                if (out != null) {
                    out.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

后端登录接口:

@RequestMapping(value = "/authlogin")
    public String authLogin(@Validated(LoginValidator.class) UserQuery query, HttpServletRequest request) {
        Cache cache = cacheManager.getCache("authCode");
        Element element = cache.get(request.getRequestedSessionId());
        if (element == null) {
            return "验证码已过期";
        }
        String authCode = element.getObjectValue().toString();
        if (authCode.equalsIgnoreCase(query.getAuthCode())) {
            Subject subject = SecurityUtils.getSubject();
            UsernamePasswordToken token = new UsernamePasswordToken(query.getUsername(), query.getPassword());
            subject.login(token);
            return "ok";
        } else {
            cache.remove(request.getRequestedSessionId());
            return "验证码错误";
        }
    }

kaptcha配置:

在resources目录下创建kaptcha.xml文件,用来配置验证码生成规则

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.1.xsd">
    <!-- Kaptcha组件配置 -->
    <bean id="kaptchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
        <property name="config">
            <bean class="com.google.code.kaptcha.util.Config">
                <constructor-arg>
                    <props>
                        <!-- 验证码宽度 -->
                        <prop key="kaptcha.image.width">120</prop>
                        <!-- 验证码高度 -->
                        <prop key="kaptcha.image.height">50</prop>
                        <!-- 生成验证码内容范围 -->
                        <prop key="kaptcha.textproducer.char.string">3457acdefhkmnprstuvwxyACDEFGHKLMNPQRSTUVWXY</prop>
                        <!-- 验证码个数 -->
                        <prop key="kaptcha.textproducer.char.length">4</prop>
                        <!-- 是否有边框 -->
                        <prop key="kaptcha.border">no</prop>
                        <!-- 边框颜色 -->
                        <prop key="kaptcha.border.color">105,179,90</prop>
                        <!-- 边框厚度 -->
                        <prop key="kaptcha.border.thickness">1</prop>
                        <!-- 验证码字体颜色 -->
                        <prop key="kaptcha.textproducer.font.color">yellow</prop>
                        <!-- 验证码字体大小 -->
                        <prop key="kaptcha.textproducer.font.size">30</prop>
                        <!-- 验证码所属字体样式 -->
                        <prop key="kaptcha.textproducer.font.names">楷体</prop>
                        <!-- 干扰线颜色 -->
                        <prop key="kaptcha.noise.color">black</prop>
                        <!-- 验证码文本字符间距 -->
                        <prop key="kaptcha.textproducer.char.space">8</prop>
                        <!-- 图片样式 :阴影-->
                        <prop key="kaptcha.obscurificator.impl">com.google.code.kaptcha.impl.ShadowGimpy</prop>
                        <!-- 去除干扰线 -->
                        <prop key="kaptcha.noise.impl">com.google.code.kaptcha.impl.NoNoise</prop>
                    </props>
                </constructor-arg>
            </bean>
        </property>
    </bean>
</beans>

Spring Boot验证码配置类

@Configuration
@ImportResource(locations = "classpath:kaptcha.xml")
public class CaptchaConfig {
}

Ehcache相关配置:

在resources目录配置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">
    <defaultCache
        maxElementsInMemory="10000"
        eternal="false"
        timeToIdleSeconds="300"
        timeToLiveSeconds="300"
        overflowToDisk="false"
        diskPersistent="false"
    />

    <cache name="authCode"
           maxEntriesLocalHeap="0"
           eternal="false"
           timeToIdleSeconds="60"
           timeToLiveSeconds="60"
           overflowToDisk="false"
           statistics="true">
    </cache>
</ehcache>

application.yml

spring:
  cache:
    ehcache:
      config: classpath:ehcache.xml

pom.xml依赖

<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>
<dependency>
    <groupId>com.github.penggle</groupId>
    <artifactId>kaptcha</artifactId>
    <version>2.3.2</version>
</dependency>

效果图
image.png

# Lombok # Dubbo # Jenkins # RabbitMQ # Zookeeper # IDEA # Logstash # Kibana # ELK # NIO # Netty # Spring Cloud # Golang # DataX # Elasticsearch # React Native # Mysql # H2 # Socket # Spring Boot # Kafka # Mybatis # Sqlmap # Vue # Postgresql # Docker # Vert.x # Flutter # Flink # Redis
Java数据同步
Flink安装排坑指南
  • 文章目录
  • 站点概览
会Coding的猴子

会Coding的猴子

58 日志
20 分类
30 标签
RSS
Github
Creative Commons
© 2021 会Coding的猴子
由 Halo 强力驱动
|
主题 - NexT.Gemini v5.1.4

湘ICP备18011740号