zoukankan      html  css  js  c++  java
  • Java Web项目使用图形验证码 — Kaptcha

    一、验证码介绍

    生成的主要方式:

    1.使用Java原生的方式,其中包含了Servlet、AWT、ImageIO的使用;

    2.使用开源库,例如Jcaptcha、Kaptcha...;

        (各图形验证码开源库:http://www.oschina.net/project/tag/248/captcha?lang=19

    另外,生成code可以保存在Session或Cookie,也可以保存在缓存(例如,Redis);

    需要验证的时候,需要把从Session或者缓存中取出并与请求的验证码进行校验;

    二、项目中使用验证码

    项目中使用的是Google的开源库 - Kaptcha;注意:本项目使用了Spring MVC;

    1.引入Maven

    <dependency>
        <groupId>com.google.code</groupId>
        <artifactId>kaptcha</artifactId>
        <version>2.3.2</version>
    </dependency>

    2.Spring配置Bean

    更多Kaptcha配置请移步底部资料;

        <!--图形验证码-->
        <bean id="captchaProducer" class="com.google.code.kaptcha.impl.DefaultKaptcha">
            <property name="config">
                <bean class="com.google.code.kaptcha.util.Config">
                    <constructor-arg type="java.util.Properties">
                        <value>
                            kaptcha.border=yes
                        </value>
                    </constructor-arg>
                </bean>
            </property>
        </bean>

    3.Controller中代码实现

    @RestController
    @RequestMapping(value = "/verify", name = "图片验证码")
    public class ValidateCoderController {
    
        private Logger logger = LoggerFactory.getLogger(ValidateCoderController.class);
    
        @Autowired
        private Producer captchaProducer;
    
        @RequestMapping(value = "/code", method = RequestMethod.GET, name = "图片验证码")
        public void code(HttpServletResponse response,
                         @RequestParam(value = "mobilePhone", required = true) String mobilePhone,
                         @RequestParam(value = "captchaType", required = true) Integer captchaType) {
            if (!StrUtils.isPhoneNumber(mobilePhone)) {
                return;
            }
            CaptchaType type = getCaptchaTypeByCode(captchaType);
            if (isTooOften(mobilePhone, type.getValue())) {
                logger.info("号码{}获取{}图片验证码频繁", mobilePhone, type.getBundleKey());
                return;
            }
    
            response.setDateHeader("Expires", 0);
            response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
            response.addHeader("Cache-Control", "post-check=0, pre-check=0");
            response.setHeader("Pragma", "no-cache");
            response.setContentType("image/jpeg");
            try (ServletOutputStream out = response.getOutputStream()) {
                String capText = captchaProducer.createText().substring(0, 4);
                BufferedImage bi = captchaProducer.createImage(capText);
                ImageIO.write(bi, "jpg", out);
                //设置验证码
                RedisConnector.save(mobilePhone, capText, type.getValue());
                
                /*移动端需要base64处理后返回,然后response的Headers不用配置;
                  此处需要使用ByteArrayOutputStream
                BASE64Encoder encoder = new BASE64Encoder();
                String base64String = encoder.encode(out.toByteArray());
                */
            } catch (IOException e) {
                e.printStackTrace();
                logger.error("号码{}获取{}图片验证码失败", mobilePhone, type.getBundleKey());
            }
        }
    
        private boolean isTooOften(String mobilePhone, String loginPre) {
            String key = KeyUtils.getLimitKey(mobilePhone, loginPre);
            if (RedisConnector.exists(key)) {
                String countStr = RedisConnector.getData(key);
                int count = Integer.parseInt(countStr);
                if (count >= 30) {
                    return true;
                }
            }
            return false;
        }
    }

    4.验证码校验

    需要使用的地方从Redis取出校验,这里需要注意的是:

        1)Redis的Keys的生成工具类KeysUtils;

        2)操作Redis的工具,以及Code的有效时间;

        3)校验验证码成功需要使其失效;

    Java原生方式:

    http://tedhacker.top/2016/11/07/Java%E7%94%9F%E6%88%90%E9%AA%8C%E8%AF%81%E7%A0%81%E7%AE%80%E8%AE%B0/

    https://www.jianshu.com/p/05409731abb8

    使用Kaptcha:

    https://www.jianshu.com/p/3a695783c5c1

    http://blog.csdn.net/rambo_china/article/details/7720181

     
  • 相关阅读:
    使用反射和HttpServlet类制作一个简单的web层框架
    [剑指offer]跳台阶问题&动态规划求解
    [剑指offer]旋转数组的最小值
    java实现大锤的自动校对程序(字节校招,字符串问题)
    栈结构的java实现&括号匹配问题
    单链表结构及链表反转操作java代码实现
    排序算法的java实现
    Ajax+JSON
    Jquery
    Filter+Listener
  • 原文地址:https://www.cnblogs.com/itommy/p/10644562.html
Copyright © 2011-2022 走看看