Springboot 生成字符串,运算,滑动验证码
技术:springboot+kaptcha+session+字符串,运算,滑动验证码
概述
场景介绍 验证码,用于web网站。用户点击验证码图片后,生成验证码。提交后,用户输入验证码和Session验证码,进行校验。
详细
功能演示
一、目录结构
二、功能讲解
(1)字符串验证码
@Controller public class CharVerificationCodeController { @RequestMapping(value = {"/"}) public String index() { return "/index"; } //--------------------------------------字符验证码开始-------------------------------------- /** * 字符验证码Session */ public static final String SESSION_CHAR_VERIFICATION_CODE = "session_char_verification_code"; /** * 字符验证码图片 */ @RequestMapping(value = {"/charVerificationCode"}) public void charVerificationCode(HttpServletRequest request, HttpServletResponse response) throws Exception{ HashMap<String,Object> verificationCodeMap = CharVerificationCodeUtil.charVerificationCode(); CommonUtil.validateCode(request,response,verificationCodeMap,SESSION_CHAR_VERIFICATION_CODE); } /** * 检查字符验证码是否正确 * validateCode 前端输入的验证码 */ @RequestMapping("/checkCharVerificationCode") @ResponseBody public JSONResponse checkCharVerificationCode(HttpServletRequest request,@RequestParam("charVerificationCode")String charVerificationCode) { String sessionVerificationCode = (String)request.getSession().getAttribute(SESSION_CHAR_VERIFICATION_CODE); return JSONResponse.success(checkVerificationCodeMap(sessionVerificationCode,charVerificationCode)); } //--------------------------------------字符验证码结束-------------------------------------- private HashMap<String,Object> checkVerificationCodeMap(String sessionVerificationCode,String verificationCode){ HashMap<String,Object> returnMap = new HashMap<>(); if(sessionVerificationCode == null){ returnMap.put("status",null);//验证码过期 }else if(sessionVerificationCode.equals(verificationCode)){ returnMap.put("status",true);//验证码正确 }else if(!sessionVerificationCode.equals(verificationCode)){ returnMap.put("status",false);//验证码不正确 } return returnMap; } }
(2)运算验证码
public class OperationVerificationCodeController { //--------------------------------------运算验证码开始-------------------------------------- /** * 运算验证码Session */ public static final String SESSION_OPERATION_VERIFICATION_CODE = "session_operation_verification_code"; /** * 运算验证码图片 */ @RequestMapping(value = {"/operationVerificationCode"}) public void operationVerificationCode(HttpServletRequest request, HttpServletResponse response) throws Exception{ HashMap<String,Object> verificationCodeMap = OperationVerificationCodeUtil.operationVerificationCode(); CommonUtil.validateCode(request,response,verificationCodeMap,SESSION_OPERATION_VERIFICATION_CODE); } /** * 检查运算验证码是否正确 * validateCode 前端输入的验证码 */ @RequestMapping("/checkOperationVerificationCode") @ResponseBody public JSONResponse checkOperationVerificationCode(HttpServletRequest request,@RequestParam("operationVerificationCode")String operationVerificationCode) { String sessionVerificationCode = (String)request.getSession().getAttribute(SESSION_OPERATION_VERIFICATION_CODE); return JSONResponse.success(checkVerificationCodeMap(sessionVerificationCode,operationVerificationCode)); } //--------------------------------------运算验证码结束-------------------------------------- private HashMap<String,Object> checkVerificationCodeMap(String sessionVerificationCode,String verificationCode){ HashMap<String,Object> returnMap = new HashMap<>(); if(sessionVerificationCode == null){ returnMap.put("status",null);//验证码过期 }else if(sessionVerificationCode.equals(verificationCode)){ returnMap.put("status",true);//验证码正确 }else if(!sessionVerificationCode.equals(verificationCode)){ returnMap.put("status",false);//验证码不正确 } return returnMap; } }
(3)滑动验证码
@Controller public class SlideVerificationCodeController { //获取端口号 @Value("${server.port}") private String serverPort; //--------------------------------------滑动验证码开始-------------------------------------- /** * 滑动验证码Session */ public static final String SESSION_SLIDE_VERIFICATION_CODE = "session_slide_verification_code"; @RequestMapping("/slideVerificationCode") @ResponseBody /** * 滑动验证码图片 */ public JSONResponse slideVerificationCode(HttpServletRequest request){ String localPath = "http://127.0.0.1:"+serverPort+"/img/slide.jpg"; SlideVerificationCode slideCode = SlideVerificationCodeUtil.slideVerificationCode(localPath); HashMap<String,Object> returnMap = new HashMap<>(); returnMap.put("originalImage",slideCode.getOriginalImage()); returnMap.put("cutImage",slideCode.getCutImage()); returnMap.put("yLocation",slideCode.getyLocation()); System.out.println("------------"+"滑动验证码:xLocation:"+slideCode.getxLocation()+"------------"); int xLocation = (Integer) (slideCode.getxLocation()); request.getSession().setAttribute(SESSION_SLIDE_VERIFICATION_CODE, xLocation); return JSONResponse.success(returnMap); } /** * 检查滑动验证码是否正确 * validateCode 前端输入的x坐标 */ @RequestMapping("/checkSlideVerificationSlideX") @ResponseBody public JSONResponse checkSlideVerificationSlideX(HttpServletRequest request,@RequestParam("slideVerificationCode")int slideX) { Integer sessionVerificationSlideX = (Integer) request.getSession().getAttribute(SESSION_SLIDE_VERIFICATION_CODE); return JSONResponse.success(checkSlideVerificationSlideXMap(sessionVerificationSlideX,slideX)); } //--------------------------------------滑动验证码结束-------------------------------------- private HashMap<String,Object> checkSlideVerificationSlideXMap(Integer sessionVerificationSlideX,int slideX){ int threshold = 8; //8像素的误差 HashMap<String,Object> returnMap = new HashMap<>(); if(sessionVerificationSlideX == null){ returnMap.put("status",null);//验证码过期 return returnMap; } if((Math.abs(sessionVerificationSlideX - slideX) <= threshold) ){ returnMap.put("status",true);//验证码正确 }else{ returnMap.put("status",false);//验证码不正确 } return returnMap; } }
(4)前端页面
<!DOCTYPE html> <html lang="en"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>SpringBoot 生成验证码</title> <link href="/css/slider.css" rel="stylesheet"> <script type="text/javascript" src="/js/jquery/jquery-3.3.1.min.js"></script> <script src="/js/slider.js"></script> <script type='text/javascript'> //--------------------------------------字符验证码开始-------------------------------------- //绑定事件,键松开检查验证码是否正确 $(function () { $("#charVerificationCodeInput").keyup(function(){ checkCharVerificationCode($(this).val()); }); }); //更新字符串验证码图片 function uploadCharVerificationCode() { $("#charVerificationCode").attr("src","/charVerificationCode?random="+new Date().getMilliseconds()); } //检查字符串验证码 function checkCharVerificationCode(charVerificationCode) { var error = $("#charVerificationCodeError"); if(charVerificationCode != null && charVerificationCode != ""){ $.ajax({ type: "POST", async:false, url: "/checkCharVerificationCode?charVerificationCode="+charVerificationCode, success : function(jsonData) { if(jsonData.code == 200) { var data = jsonData.data; var status = data.status; if (status == true) { error.html("恭喜你,字符串验证码正确!!!!!"); } else if(status == false){ error.html("字符串验证码错误,请重新输入"); }else{ error.html("字符串验证码过期,请重新输入"); uploadCharVerificationCode(); } }else{ alert(jsonData.message); } return false; }, error:function(XMLHttpRequest,textStatus,errorThrown){ alert("服务器错误!状态码:"+XMLHttpRequest.status); // 状态 console.log(XMLHttpRequest.readyState); // 错误信息 console.log(textStatus); return false; } }); }else{ error.html("请输入验证码!"); } } //--------------------------------------字符验证码结束-------------------------------------- //--------------------------------------运算验证码开始-------------------------------------- //绑定事件,键松开检查验证码是否正确 $(function () { $("#operationVerificationCodeInput").keyup(function(){ checkOperationVerificationCode($(this).val()); }); }); //更新运算验证码图片 function uploadOperationVerificationCode() { $("#operationVerificationCode").attr("src","/operationVerificationCode?random="+new Date().getMilliseconds()); } //检查运算验证码 function checkOperationVerificationCode(operationVerificationCode) { var error = $("#operationVerificationCodeError"); if(operationVerificationCode != null && operationVerificationCode != ""){ $.ajax({ type: "POST", async:false, url: "/checkOperationVerificationCode?operationVerificationCode="+operationVerificationCode, success : function(jsonData) { if(jsonData.code == 200) { var data = jsonData.data; var status = data.status; if (status == true) { error.html("恭喜你,运算验证码正确!!!!!"); } else if(status == false){ error.html("运算验证码错误,请重新输入"); }else{ error.html("运算验证码过期,请重新输入"); uploadOperationVerificationCode(); } }else{ alert(jsonData.message); } return false; }, error:function(XMLHttpRequest,textStatus,errorThrown){ alert("服务器错误!状态码:"+XMLHttpRequest.status); // 状态 console.log(XMLHttpRequest.readyState); // 错误信息 console.log(textStatus); return false; } }); }else{ error.html("请输入验证码!"); } } //--------------------------------------运算证码结束-------------------------------------- </script> </head> <body> <p> </p> <div> 字符验证码: <img id="charVerificationCode" width="150" height="50" style="cursor: pointer;" src="/charVerificationCode" onclick="uploadCharVerificationCode();"> <p> 验证码验证:<input type="text" id="charVerificationCodeInput" /> </p> <p id="charVerificationCodeError" style="color:red;font-weight:bold"></p> </div> <p> </p> <div> 运算验证码: <img id="operationVerificationCode" width="185" height="50" style="cursor: pointer;" src="/operationVerificationCode" onclick="uploadOperationVerificationCode();"> <p> 验证码验证:<input type="text" id="operationVerificationCodeInput" /> </p> <p id="operationVerificationCodeError" style="color:red;font-weight:bold"></p> </div> <p> </p> <div> 滑动验证码: <div class="slide_img_content"> <div class="slide_img"> <img class="slide_refresh" src="/icon/refresh.png" onclick="uploadSlideVerificationCode();"> <img id="cutImage" class="slide_img_mark" > <img id="originalImage"> </div> </div> <div class="slider_clear"> <div class="slider"> <div class="slider_arror" style="cursor:pointer;" onselectstart="return false;"> <img style="margin-top: 5px;" id="arror_icon" src="/icon/right_arror.png" draggable="false" width="30px" height="30px"> </div> <div class="slider_mask"> </div> <span class="slider_tip" onselectstart="return false;">向右拖动滑块填充拼图</span> </div> </div> <p id="slideVerificationCodeError" style="color:red;font-weight:bold"></p> </div> </body> </html>
滑动js,slider.js
var sliderStart = false; var x_slider,y_slider; // 鼠标最初位置 var original_image_with_slider = 300;//边界宽度 = 图片宽度 var cut_image_width_slider = 50;//剪切图宽度 var yLocation; // 数据返回 x y $(function(){ uploadSlideVerificationCode(); }); function uploadSlideVerificationCode() { resetSlide(); //拼图验证码用---修改位置和重置颜色 $.ajax({ type: "POST", async:false, url: "/slideVerificationCode?random="+new Date().getMilliseconds(), success : function(jsonData) { if(jsonData.code == 200) { var data = jsonData.data; yLocation = data.yLocation; initImgSlide(data.originalImage, data.cutImage, yLocation); initMovementSlide(); $("#slideVerificationCodeError").html(""); }else{ alert(jsonData.message); } return false; }, error:function(XMLHttpRequest,textStatus,errorThrown){ alert("服务器错误!状态码:"+XMLHttpRequest.status); // 状态 console.log(XMLHttpRequest.readyState); // 错误信息 console.log(textStatus); return false; } }); } //图片显示使用base64时的前缀,src=base64PrefixPathSlide + imgBase64Value var base64PrefixPathSlide="data:image/png;base64,"; // 拼图验证码用---初始化图片 function initImgSlide(originalImage, cutImage, yLocation){ $('#originalImage').prop('src', base64PrefixPathSlide+originalImage); $('#cutImage').prop('src', base64PrefixPathSlide+cutImage); $('.slide_img_mark').css('margin-top', yLocation); } // 拼图验证码用---设置回调 function initMovementSlide(){ $('.slider_arror')[0].addEventListener('mousedown', sliderPush); window.addEventListener('mousemove', sliderDrug); window.addEventListener('mouseup', sliderEnd); } // 拼图验证码用---按下滑动按钮回调方法 function sliderPush(e){ sliderStart = true x_slider = e.clientX || e.touches[0].clientX; y_slider = e.clientY || e.touches[0].clientY; $('.slider_tip').hide(); $('.slider_mask').css('background-color', '#deee97'); $('#arror_icon').prop('src', '/icon/right_arror.png'); } // 拼图验证码用---开始滑动回调方法, 改变arror位置和mask大小 function sliderDrug(e){ if (!sliderStart) return false; // 获取鼠标移动位置 var eventX = e.clientX || e.touches[0].clientX; var eventY = e.clientY || e.touches[0].clientY; var moveX = eventX - x_slider; var moveY = eventY - y_slider; // 确保边界 if(moveX < 0|| moveX + parseInt(cut_image_width_slider) > original_image_with_slider){ return false; } // 改变slider_arror的位置和mask大小 $('.slider_arror').css('margin-left', moveX); $('.slider_arror').css('cursor', 'pointer'); $('.slider_mask').css('width', moveX); $('.slide_img_mark').css('margin-left', moveX); } // 拼图验证码用---结束时进行判断回调方法 function sliderEnd(e){ if (!sliderStart) return false; sliderStart = false; var finalX = $('.slide_img_mark').css('margin-left'); finalX = finalX.toString().slice(0, -2); var error = $("#slideVerificationCodeError"); $.ajax({ type: "POST", async:false, url: "/checkSlideVerificationSlideX?slideVerificationCode="+finalX, success : function(jsonData) { if(jsonData.code == 200) { var data = jsonData.data; var status = data.status; if (status == true) { error.html("恭喜你,滑动验证码正确!!!!!"); successSlide(); } else if(status == false){ error.html("滑动验证码错误,请重新滑动"); failedSlide(); }else{ error.html("滑动验证码过期,请重新滑动"); failedSlide(); } }else{ alert(jsonData.message); } return false; }, error:function(XMLHttpRequest,textStatus,errorThrown){ alert("服务器错误!状态码:"+XMLHttpRequest.status); // 状态 console.log(XMLHttpRequest.readyState); // 错误信息 console.log(textStatus); return false; } }); } // 拼图验证码用---验证成功回调方法 function successSlide(){ $('#arror_icon').prop('src', '/icon/green_correct.png'); $('.slider_mask').css('background-color', '#79e77e'); } // 拼图验证码用---失败重置 function failedSlide(){ $('#arror_icon').prop('src', '/icon/red_error.png'); $('.slider_mask').css('background-color', '#e73c4a'); setTimeout(resetSlide, 1000) } // 拼图验证码用---修改位置和重置颜色 function resetSlide(){ $('.slider_mask').css('background-color', '#deee97'); $('.slider_arror').css('margin-left', 0); $('.slider_arror').css('cursor','pointer'); $('.slider_mask').css('width', 0); $('.slide_img_mark').css('margin-left', 0); $('#arror_icon').prop('src', '/icon/right_arror.png'); $('.slider_tip').show() }
三、运行
吐槽环节:百度的搜java 验证码,太坑爹了,各种各样复杂,非常不通用,还有一些不能运行的。忍不了忍不了,自己整合一个,最后找到google kaptcha 工具 vary good !!!
谢谢大家观看~
本实例支付的费用只是购买源码的费用,如有疑问欢迎在文末留言交流,如需作者在线代码指导、定制等,在作者开启付费服务后,可以点击“购买服务”进行实时联系,请知悉,谢谢
手机上随时阅读、收藏该文章 ?请扫下方二维码