滑動驗證的設計與實現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/)技術文檔
