zoukankan      html  css  js  c++  java
  • 登录验证码开发记录

    登录验证码开发记录

    后台使用了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>
    

    效果图

  • 相关阅读:
    协议与接口相关
    jmeter 使用(1)
    jmeter 压力测试
    shell脚本的规则
    charles的原理及使用
    Linux环境部署和项目构建
    面向对象
    python 基础练习题
    jmeter 使用(2)
    Ext.apply
  • 原文地址:https://www.cnblogs.com/dagger9527/p/12691574.html
Copyright © 2011-2022 走看看