服务器开发之图形验证码

BrandyDunro 8年前
   <p style="text-align: center;"><img src="https://simg.open-open.com/show/fa91364173c93ef3f5328a7709b12cca.jpg"></p>    <h2><strong>验证码</strong></h2>    <p>验证码是一种区分用户是计算机还是人的公共全自动程序。短时间是无法退出人类舞台的,目前只是尽量提升用户体验。</p>    <h2><strong>作用</strong></h2>    <ul>     <li> <p>账号安全</p> </li>     <li> <p>反作弊</p> </li>     <li> <p>反爬虫</p> </li>     <li> <p>防论坛灌水</p> </li>     <li> <p>防恶意注册</p> </li>    </ul>    <h2><strong>分类</strong></h2>    <ul>     <li> <p>图形验证码</p> </li>     <li> <p>Gif动画验证码</p> </li>     <li> <p>手机短信验证码</p> </li>     <li> <p>手机语音验证码</p> </li>     <li> <p>视频验证码</p> </li>     <li> <p>web2.0验证码</p> </li>    </ul>    <h2><strong>kaptcha验证码组件</strong></h2>    <h2><strong>简介</strong></h2>    <p>kaptcha 是一个非常实用的验证码生成工具。有了它,你可以生成各种样式的验证码,因为它是可配置的。</p>    <h2><strong>常见配置</strong></h2>    <ul>     <li> <p>验证码的字体</p> </li>     <li> <p>验证码字体的大小</p> </li>     <li> <p>验证码字体的字体颜色</p> </li>     <li> <p>验证码内容的范围(数字,字母,中文汉字!)</p> </li>     <li> <p>验证码图片的大小,边框,边框粗细,边框颜色</p> </li>     <li> <p>验证码的干扰线(可以自己继承com.google.code.kaptcha.NoiseProducer写一个自定义的干扰线)</p> </li>     <li> <p>验证码的样式(鱼眼样式、3D、普通模糊……当然也可以继承com.google.code.kaptcha.GimpyEngine自定义样式)</p> </li>    </ul>    <h2><strong>maven</strong></h2>    <pre>  <code class="language-java"><dependency>      <groupId>com.github.axet</groupId>      <artifactId>kaptcha</artifactId>      <version>0.0.9</version>  </dependency></code></pre>    <h2><strong>kaptcha.properties</strong></h2>    <pre>  <code class="language-java">kaptcha.textproducer.font.color=red  kaptcha.image.width=130  kaptcha.image.height=44  kaptcha.textproducer.font.size=35  kaptcha.textproducer.char.length=4  kaptcha.textproducer.font.names=\\u5B8B\\u4F53,\\u6977\\u4F53,\\u5FAE\\u8F6F\\u96C5\\u9ED1  kaptcha.noise.color=gray  kaptcha.obscurificator.impl=com.google.code.kaptcha.impl.WaterRipple</code></pre>    <h2><strong>代码具体实现</strong></h2>    <p>本代码主要用filter过滤器来生成验证码。</p>    <h2><strong>web.xml</strong></h2>    <pre>  <code class="language-java"><filter>      <filter-name>KaptchaFilter</filter-name>      <filter-class>com.xxoo.admin.ui.filter.KaptchaFilter</filter-class>  </filter>  <filter-mapping>      <filter-name>KaptchaFilter</filter-name>      <url-pattern>/kaptcha.jpg</url-pattern>  </filter-mapping></code></pre>    <p>注意:验证码过滤器需要放到Shiro之后,因为Shiro将包装HttpSession.如果不,可能造成两次的sesisonid不一样。</p>    <h2><strong>图片验证码类</strong></h2>    <pre>  <code class="language-java">public class CaptchaService {        private static ImageCaptchaService instance = null;        static {          instance = new KaptchaImageCaptchaService();      }        public synchronized static ImageCaptchaService getInstance() {          return instance;      }        public synchronized static boolean validate(HttpServletRequest httpServletRequest, String input) throws Exception {          String text = instance.getText(httpServletRequest);          boolean result = text.equalsIgnoreCase(input);          instance.removeKaptcha(httpServletRequest);          return result;      }  }</code></pre>    <h2><strong>基于Kaptcha的验证码图片实现</strong></h2>    <pre>  <code class="language-java">public class KaptchaImageCaptchaService implements ImageCaptchaService {        private Logger logger = LoggerFactory.getLogger(getClass());        public KaptchaImageCaptchaService() {      }        public static Config getConfig() throws IOException {          Properties p = new Properties();          p.load(new DefaultResourceLoader().getResource("kaptcha.properties").getInputStream());          Config config = new Config(p);          return config;      }        @Override      public void create(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {          httpServletResponse.setDateHeader("Expires", 0L);          httpServletResponse.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");          httpServletResponse.addHeader("Cache-Control", "post-check=0, pre-check=0");          httpServletResponse.setHeader("Pragma", "no-cache");          httpServletResponse.setContentType("image/jpeg");          Config config = getConfig();          Producer producer = config.getProducerImpl();          String capText = producer.createText();          if(logger.isDebugEnabled()){              logger.info("create captcha:" + capText + ":" + config.getSessionKey() );          }          httpServletRequest.getSession().setAttribute(config.getSessionKey(), capText);          httpServletRequest.getSession().setAttribute(config.getSessionDate(), new Date());          BufferedImage bi = producer.createImage(capText);          ServletOutputStream out = httpServletResponse.getOutputStream();          ImageIO.write(bi, "jpg", out);          out.flush();          out.close();      }        @Override      public String getText(HttpServletRequest httpServletRequest) throws Exception {          return (String)httpServletRequest.getSession().getAttribute(getConfig().getSessionKey());      }        @Override      public void removeKaptcha(HttpServletRequest httpServletRequest) throws Exception {          httpServletRequest.getSession().removeAttribute(getConfig().getSessionKey());          httpServletRequest.getSession().removeAttribute(getConfig().getSessionDate());      }    }</code></pre>    <h2><strong>验证码工具类</strong></h2>    <pre>  <code class="language-java">public class CaptchaService {        private static ImageCaptchaService instance = null;        static {          instance = new KaptchaImageCaptchaService();      }        public synchronized static ImageCaptchaService getInstance() {          return instance;      }        public synchronized static boolean validate(HttpServletRequest httpServletRequest, String input) throws Exception {          String text = instance.getText(httpServletRequest);          boolean result = text.equalsIgnoreCase(input);          instance.removeKaptcha(httpServletRequest);          return result;      }  }</code></pre>    <h2><strong>生成验证码过滤器</strong></h2>    <pre>  <code class="language-java">public class KaptchaFilter extends OncePerRequestFilter {        private Logger logger = LoggerFactory.getLogger(getClass());        @Override      protected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {          try {              CaptchaService.getInstance().create(httpServletRequest,httpServletResponse);          } catch (Exception e) {              logger.info("create captcha error.",e);          }      }    }</code></pre>    <h2><strong>验证码校验</strong></h2>    <pre>  <code class="language-java">private boolean doCaptchaValidate(HttpServletRequest request, String code) {          //比对          try {              if (code == null || !CaptchaService.validate(request, code)) {                  return false;              } else {                  return true;              }          } catch (Exception e) {              logger.warn("captcha check error!");              return false;          }  }</code></pre>    <h2><strong>小结</strong></h2>    <p>本文主要讲述了kaptcha图形化验证码的使用和介绍,小伙伴可以根据自己的需求进行引入;后面会继续介绍web2.0极验证。</p>    <p> </p>    <p>来自:http://www.jianshu.com/p/90963f73ad5b</p>    <p> </p>