滑动验证的设计与实现J2EE
注:本博文为博主原创,转载请注明出处。
项目源码地址:https://github.com/zhangxy1035/Verify
本篇博文的主要目录如下:
一、项目简介
二、项目演示
2.1滑动验证演示
2.2验证码演示
三、项目构建
3.1滑动验证的项目构建
3,2验证码生成与实现
四、项目总结以及参考资料
一、项目简介
验证码在网页中随处可见,它主要是防止对某一个特定注册用户用特定程序进行暴力破解方式不断的登陆尝试。现在大多数的验证包括,字符验证码、文字验证等。在本博文中也实现了一般验证码的生成。但是本文的重点还是放在了基于极验插件实现的滑动验证功能。
二、项目演示
2.1滑动验证演示
2.2验证码验证
三、项目构建
3.1滑动验证项目构建
在滑动验证中,使用了第三方的插件极验(http://www.geetest.com/)。在极验的官方文档中介绍比较详细,什么样的后台,用什么样的代码,并且如何将这个插件集成在自己的项目中,在本节,我们将主要完成极验插件与Java Web的集成。
先来一张极验的原理图(图片来源:http://www.geetest.com/install/sections/idx-main-frame.html)
首先在极验平台上下载所需的平台插件。http://www.geetest.com/install/(以Java为例)。在认真阅读极验技术文档后,在https://github.com/GeeTeam/gt-java-sdk上下载插件。在插件中的主要类的代码如下。
GeetestLib.java(这个类是主要的类,必须在文件中包含)
GeetestConfig.java(基础的配置信息,比较重要的为id,key)
1 // 填入自己的captcha_id和private_key 2 private static final String geetest_id = "72ddccf637ee857411051fe81f66412e"; 3 private static final String geetest_key = "fc84991f179bc1f9210556739f62c9ff";
StartCaptchaServlet.java(Servlet,这个类所在的包一定要和web.xml文件中保持一致)
web.xml(因为要融合到自己的项目中,所以在此之前我们需要新建一个java web项目,然后在web.xml文件中增加以下内容)
1 <servlet> 2 <servlet-name>StartCaptchaServlet</servlet-name> 3 <servlet-class>com.controller.login.StartCaptchaServlet</servlet-class> 4 </servlet> 5 6 <servlet-mapping> 7 <servlet-name>StartCaptchaServlet</servlet-name> 8 <url-pattern>/login/pc-geetest/register</url-pattern> 9 </servlet-mapping>
其中上图中的关于servlet配置和普通的配置是一样的。只是在此需要注意<url-pattern>这个应该和自己的实际路径保持一致,并且要与前台页面中的也需要一致,前台页面中url为pc-geetest/register,这里却是/login/pc-geetest/register,这是由于,我本身的项目中用到了SpringMVC地址多映射了一层。
login.jsp
1 <script src="http://code.jquery.com/jquery-1.12.3.min.js"></script> 2 <!-- 引入封装了failback的接口--initGeetest --> 3 <script src="http://static.geetest.com/static/tools/gt.js"></script> 4 5 <form id="loginForm" action="login.from" method="post"> 6 <p> 7 <input type="text" id="username2" name="username" placeholder="用户名" class="form-control top"> 8 <input type="password" id="password2" name="password" placeholder="密码" class="form-control top"> 9 10 <div id="embed-captcha"></div> 11 <p id="wait" class="show">正在加载验证码......</p> 12 <p id="notice" class="hide">请先拖动验证码到相应位置</p> 13 14 <br> 15 <button class="btn btn-lg btn-primary btn-block" id="embed-submit" onclick="doSubmit();">登陆</button> 16 </form> 17 18 <script> 19 var handlerEmbed = function (captchaObj) { 20 $("#embed-submit").click(function (e) { 21 var validate = captchaObj.getValidate(); 22 if (!validate) { 23 $("#notice")[0].className = "show"; 24 setTimeout(function () { 25 $("#notice")[0].className = "hide"; 26 }, 2000); 27 e.preventDefault(); 28 } 29 }); 30 // 将验证码加到id为captcha的元素里,同时会有三个input的值:geetest_challenge, geetest_validate, geetest_seccode 31 captchaObj.appendTo("#embed-captcha"); 32 captchaObj.onReady(function () { 33 $("#wait")[0].className = "hide"; 34 }); 35 // 更多接口参考:http://www.geetest.com/install/sections/idx-client-sdk.html 36 }; 37 $.ajax({ 38 // 获取id,challenge,success(是否启用failback) 39 url: "pc-geetest/register?t=" + (new Date()).getTime(), // 加随机数防止缓存 40 type: "get", 41 dataType: "json", 42 success: function (data) { 43 // 使用initGeetest接口 44 // 参数1:配置参数 45 // 参数2:回调,回调的第一个参数验证码对象,之后可以使用它做appendTo之类的事件 46 initGeetest({ 47 gt: data.gt, 48 challenge: data.challenge, 49 product: "embed", // 产品形式,包括:float,embed,popup。注意只对PC版验证码有效 50 offline: !data.success // 表示用户后台检测极验服务器是否宕机,一般不需要关注 51 // 更多配置参数请参见:http://www.geetest.com/install/sections/idx-client-sdk.html#config 52 }, handlerEmbed); 53 } 54 }); 55 </script>
在上述代码中比较重要的是在网页中必须引入jquery,以及,极验平台提供的js,<script src="http://static.geetest.com/static/tools/gt.js"></script>这个js主要会去加载图片,以及根据验证的ID和key进行判断。这样一个项目就构建成功了。这个实现的主要功能为,通过将小的图片移动到缺口处,即可通过验证。
3.2一般验证码项目构建
首先在这个项目中实现的一般验证码为生成了从A-Za-z0-9之中的5个随机数,将此随机数在传递到前台进行,验证码的正确与否则是通过后台进行判断。主要的代码如下:
验证码生成
1 package com.ow.appmg.controller.login; 2 3 import java.awt.Color; 4 import java.awt.Font; 5 import java.awt.Graphics; 6 import java.awt.image.BufferedImage; 7 import java.io.OutputStream; 8 import java.util.Random; 9 10 import javax.imageio.ImageIO; 11 import javax.servlet.http.HttpServletResponse; 12 import javax.servlet.http.HttpSession; 13 14 import org.springframework.stereotype.Controller; 15 import org.springframework.web.bind.annotation.RequestMapping; 16 17 @Controller 18 @RequestMapping("/login") 19 public class GetCodeController { 20 21 @RequestMapping("/getCode") 22 public void execute( 23 HttpServletResponse response, 24 HttpSession session) throws Exception{ 25 //0.创建空白图片 26 BufferedImage image = new BufferedImage(100,30,BufferedImage.TYPE_INT_RGB); 27 //1.获取图片画笔 28 Graphics g = image.getGraphics(); 29 Random r = new Random(); 30 //2.设置画笔颜色 31 g.setColor(new Color(r.nextInt(255), r.nextInt(255), r.nextInt(255))); 32 //3.绘制矩形的背景 33 g.fillRect(0, 0, 100, 30); 34 //4.调用自定义的方法,获取长度为5的字母数字组合的字符串 35 String number = getNumber(5); 36 //将图片字符存入session,用于验证码检查使用 37 session.setAttribute("scode", number); 38 g.setColor(new Color(0,0,0)); 39 g.setFont(new Font(null,Font.BOLD,24)); 40 //5.设置颜色字体后,绘制字符串 41 g.drawString(number, 5, 25); 42 //6.绘制8条干扰线 43 for(int i=0;i<8;i++){ 44 g.setColor(new Color(r.nextInt(255),r.nextInt(255),r.nextInt(255),r.nextInt(255))); 45 g.drawLine(r.nextInt(100), r.nextInt(30), r.nextInt(100), r.nextInt(30)); 46 } 47 response.setContentType("image/jpeg"); 48 OutputStream ops = response.getOutputStream(); 49 ImageIO.write(image, "jpeg", ops); 50 ops.close(); 51 } 52 53 private String getNumber(int size){ 54 String str = "qwertyuioplkjhgfdsazxcvbnmABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; 55 String number = ""; 56 Random r = new Random(); 57 for(int i=0;i<size;i++){ 58 number+=str.charAt(r.nextInt(str.length())); 59 } 60 return number; 61 } 62 }
在上述代码中使用了SpringMVC,前台通过请求可以得到从后台生成的验证码。
前台页面login.jsp
1 <form id="loginForm" action="login.from" method="post"> 2 <p class="text-muted text-center"> 3 输入用户名和密码 4 </p> 5 <input type="text" name="username" placeholder="用户名" class="form-control top"> 6 <input type="password" name="password" placeholder="密码" class="form-control top"> 7 <input name="code" type="text" placeholder="验证码" class="form-control bottom"> 8 <img src="getCode.from" alt="验证码" id="img" onclick="change()" /> 9 <div class="checkbox"> 10 <label> 11 <input type="checkbox"> 记住用户名和密码 12 </label> 13 </div> 14 <button class="btn btn-lg btn-primary btn-block" onclick="doSubmit();">登陆</button> 15 </form> 16 <script type="text/javascript"> 17 18 function doSubmit(){ 19 //表单数据js检查 20 //提交表单 21 document.getElementById("loginForm").submit(); 22 } 23 function change(){ 24 document.getElementById("img").src='getCode.from?'+new Date().getTime(); 25 }; 26 27 </script>
在本页面中也实现了一个功能,点击验证码可以进行重新请求,重新生成。函数名称为change()函数。
四、项目总结以及参考资料
在本文中主要实现了滑动验证的功能,和一般验证码生成的功能,从本质上对于用户来说都是有区别的,滑动验证可以检测是否是用户行为从而进行验证,这一点无疑是比一般验证要安全很多。
参考的资料
极验(http://www.geetest.com/)技术文档