臭味相投的朋友们,我在这里:
猿in小站:http://www.yuanin.net
csdn博客:https://blog.csdn.net/jiabeis
简书:https://www.jianshu.com/u/4cb7d664ec4b
微信免费订阅号“猿in”
滑块验证码引入
滑块验证码原理
- 从服务器随机取一张图片,并对图片上的随机x,y坐标和宽高一块区域抠图;
- 根据步骤一的坐标和宽高,使用二维数组保存原图上抠图区域的像素点坐标;
- 根据步骤二的坐标点,对原图的抠图区域的颜色进行处理。
- 完成以上步骤之后得到两张图(扣下来的方块图,带有抠图区域阴影的原图),将这两张图和抠图区域的y坐标传到前台,前端在移动方块验证时,将移动后的x坐标传递到后台与原来的x坐标作比较,如果在阈值内则验证通过。
- 请求验证的步骤:前台向后台发起请求,后台随机一张图片做处理将处理完的两张图片的base64,抠图y坐标和token(token为后台缓存验证码的唯一token,可以用缓存和分布式缓存)返回给前台。
- 前台滑动图片将x坐标和token作为参数请求后台验证,服务器根据token取出x坐标与参数的x进行比较。
滑块验证码实现
- 说明
实现是基于springmvc的实现,前端为freemarker模板。 - 工具类
package com.sikong.ms.web.shiro; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import lombok.extern.slf4j.Slf4j; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.TimeUnit; / * @Auther herb * @Description 本地缓存:用户图形验证码资源 * @Date: create in ${Time} ${Date} * @Modified By: herb */ @Slf4j public class ValidateCache { private static LoadingCache
> cache = CacheBuilder.newBuilder() .maximumSize(2) .expireAfterWrite(365, TimeUnit.DAYS) .build(createCacheLoader()); private static CacheLoader
> createCacheLoader() { return new CacheLoader
>(){ @Override public List
load(String key) throws Exception { return null; } }; } public static void set(String key,List
value){ cache.put(key,value); } public static List
get(String key){ List
value = null; try { value = cache.get(key); } catch (Exception e) { log.info("ValidateCache 缓存未查询到图片或模板!"); value = null; } return value; } public static long size(){ return cache.size(); } public static void main(String[] args) throws UnsupportedEncodingException { List
value = new ArrayList<>(); value.add("ok".getBytes("utf-8")); ValidateCache.set("121", value); ValidateCache.set("111",value); ValidateCache.set("12",value); ValidateCache.set("113",value); System.out.println(cache.size()); //注意缓存的最大容量 List
rv = ValidateCache.get("113"); System.out.println(new String(rv.get(0),"utf-8")); System.out.println(ValidateCache.size()); while (cache.size() > 0){ try { Thread.currentThread().sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } List
rv1 = ValidateCache.get("113"); System.out.println(new String(rv1.get(0),"utf-8")); } } }
package com.sikong.ms.common.captcha.validate; import lombok.extern.slf4j.Slf4j; import javax.imageio.ImageIO; import javax.imageio.ImageReadParam; import javax.imageio.ImageReader; import javax.imageio.stream.ImageInputStream; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.text.NumberFormat; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import java.util.Random; / * 滑块验证工具类 * * @author: herb * @Description: * @Date: Created in 10:57 2018/6/25 * @Modified By: */ @Slf4j public class VerifyImageUtil { private static int ORI_WIDTH = 350; //源文件宽度 private static int ORI_HEIGHT = 213; //源文件高度 private static int X; //抠图坐标x private static int Y; //抠图坐标y private static int WIDTH; //模板图宽度 private static int HEIGHT; //模板图高度 private static float xPercent; //X位置移动百分比 private static float yPercent; //Y位置移动百分比 public static int getX() { return X; } public static int getY() { return Y; } public static float getxPercent() { return xPercent; } public static float getyPercent() { return yPercent; } / * 根据模板切图 * * @param templateFile * @param targetFile * @param templateType * @param targetType * @return * @throws Exception */ public static Map
pictureTemplatesCut(byte[] templateFile, byte[] targetFile, String templateType, String targetType) throws Exception { Map
pictureMap = new HashMap<>(); // 文件类型 String templateFiletype = templateType; String targetFiletype = targetType; if (StringUtils.isEmpty(templateFiletype) || StringUtils.isEmpty(targetFiletype)) { throw new RuntimeException("file type is empty"); } // 源文件流 //File Orifile = targetFile; //InputStream oriis = new FileInputStream(Orifile); // 模板图 BufferedImage imageTemplate = ImageIO.read(new ByteArrayInputStream(templateFile)); WIDTH = imageTemplate.getWidth(); HEIGHT = imageTemplate.getHeight(); // 模板图 BufferedImage imageTarget = ImageIO.read(new ByteArrayInputStream(targetFile)); ORI_WIDTH = imageTarget.getWidth(); ORI_HEIGHT = imageTarget.getHeight(); generateCutoutCoordinates(); // 最终图像 BufferedImage newImage = new BufferedImage(WIDTH, HEIGHT, imageTemplate.getType()); Graphics2D graphics = newImage.createGraphics(); graphics.setBackground(Color.white); int bold = 5; // 获取感兴趣的目标区域 BufferedImage targetImageNoDeal = getTargetArea(X, Y, WIDTH, HEIGHT, new ByteArrayInputStream(targetFile), targetFiletype); // 根据模板图片抠图 newImage = DealCutPictureByTemplate(targetImageNoDeal, imageTemplate, newImage); // 设置“抗锯齿”的属性 graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setStroke(new BasicStroke(bold, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); graphics.drawImage(newImage, 0, 0, null); graphics.dispose(); ByteArrayOutputStream os = new ByteArrayOutputStream();//新建流。 ImageIO.write(newImage, templateFiletype, os);//利用ImageIO类提供的write方法,将bi以png图片的数据模式写入流。 byte[] newImages = os.toByteArray(); pictureMap.put("newImage", newImages); // 源图生成遮罩 BufferedImage oriImage = ImageIO.read(new ByteArrayInputStream(targetFile)); byte[] oriCopyImages = DealOriPictureByTemplate(oriImage, imageTemplate, X, Y); pictureMap.put("oriCopyImage", oriCopyImages); pictureMap.put("X",X); pictureMap.put("Y",Y); return pictureMap; } / * 根据模板切图 * * @param templateFile * @param targetFile * @param templateType * @param targetType * @return * @throws Exception */ public static Map
pictureTemplatesCut(File templateFile, File targetFile, String templateType, String targetType) throws Exception { Map
pictureMap = new HashMap<>(); // 文件类型 String templateFiletype = templateType; String targetFiletype = targetType; if (StringUtils.isEmpty(templateFiletype) || StringUtils.isEmpty(targetFiletype)) { throw new RuntimeException("file type is empty"); } // 源文件流 File Orifile = targetFile; InputStream oriis = new FileInputStream(Orifile); // 模板图 BufferedImage imageTemplate = ImageIO.read(templateFile); WIDTH = imageTemplate.getWidth(); HEIGHT = imageTemplate.getHeight(); // 模板图 BufferedImage imageTarget = ImageIO.read(Orifile); ORI_WIDTH = imageTarget.getWidth(); ORI_HEIGHT = imageTarget.getHeight(); generateCutoutCoordinates(); // 最终图像 BufferedImage newImage = new BufferedImage(WIDTH, HEIGHT, imageTemplate.getType()); Graphics2D graphics = newImage.createGraphics(); graphics.setBackground(Color.white); int bold = 5; // 获取感兴趣的目标区域 BufferedImage targetImageNoDeal = getTargetArea(X, Y, WIDTH, HEIGHT, oriis, targetFiletype); // 根据模板图片抠图 newImage = DealCutPictureByTemplate(targetImageNoDeal, imageTemplate, newImage); // 设置“抗锯齿”的属性 graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); graphics.setStroke(new BasicStroke(bold, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL)); graphics.drawImage(newImage, 0, 0, null); graphics.dispose(); ByteArrayOutputStream os = new ByteArrayOutputStream();//新建流。 ImageIO.write(newImage, templateFiletype, os);//利用ImageIO类提供的write方法,将bi以png图片的数据模式写入流。 byte[] newImages = os.toByteArray(); pictureMap.put("newImage", newImages); // 源图生成遮罩 BufferedImage oriImage = ImageIO.read(Orifile); byte[] oriCopyImages = DealOriPictureByTemplate(oriImage, imageTemplate, X, Y); pictureMap.put("oriCopyImage", oriCopyImages); pictureMap.put("X",X); pictureMap.put("Y",Y); return pictureMap; } / * 抠图后原图生成 * * @param oriImage * @param templateImage * @param x * @param y * @return * @throws Exception */ private static byte[] DealOriPictureByTemplate(BufferedImage oriImage, BufferedImage templateImage, int x, int y) throws Exception { // 源文件备份图像矩阵 支持alpha通道的rgb图像 BufferedImage ori_copy_image = new BufferedImage(oriImage.getWidth(), oriImage.getHeight(), BufferedImage.TYPE_4BYTE_ABGR); // 源文件图像矩阵 int[][] oriImageData = getData(oriImage); // 模板图像矩阵 int[][] templateImageData = getData(templateImage); //copy 源图做不透明处理 for (int i = 0; i < oriImageData.length; i++) { for (int j = 0; j < oriImageData[0].length; j++) { int rgb = oriImage.getRGB(i, j); int r = (0xff & rgb); int g = (0xff & (rgb >> 8)); int b = (0xff & (rgb >> 16)); //无透明处理 rgb = r + (g << 8) + (b << 16) + (255 << 24); ori_copy_image.setRGB(i, j, rgb); } } for (int i = 0; i < templateImageData.length; i++) { for (int j = 0; j < templateImageData[0].length - 5; j++) { int rgb = templateImage.getRGB(i, j); //对源文件备份图像(x+i,y+j)坐标点进行透明处理 if (rgb != && rgb <= 0) { int rgb_ori = ori_copy_image.getRGB(x + i, y + j); int r = (0xff & rgb_ori); int g = (0xff & (rgb_ori >> 8)); int b = (0xff & (rgb_ori >> 16)); rgb_ori = r + (g << 8) + (b << 16) + (150 << 24); ori_copy_image.setRGB(x + i, y + j, rgb_ori); } else { //do nothing } } } ByteArrayOutputStream os = new ByteArrayOutputStream();//新建流。 ImageIO.write(ori_copy_image, "png", os);//利用ImageIO类提供的write方法,将bi以png图片的数据模式写入流。 byte b[] = os.toByteArray();//从流中获取数据数组。 return b; } / * 根据模板图片抠图 * * @param oriImage * @param templateImage * @return */ private static BufferedImage DealCutPictureByTemplate(BufferedImage oriImage, BufferedImage templateImage, BufferedImage targetImage) throws Exception { // 源文件图像矩阵 int[][] oriImageData = getData(oriImage); // 模板图像矩阵 int[][] templateImageData = getData(templateImage); // 模板图像宽度 try { for (int i = 0; i < templateImageData.length; i++) { // 模板图片高度 for (int j = 0; j < templateImageData[0].length; j++) { // 如果模板图像当前像素点不是白色 copy源文件信息到目标图片中 int rgb = templateImageData[i][j]; if (rgb != && rgb <= 0) { targetImage.setRGB(i, j, oriImageData[i][j]); } } } } catch (ArrayIndexOutOfBoundsException e) {/*数组越界错误处理,这样页面就不会返回图像问题。*/ log.error("X:"+X+ "||Y:"+Y,e); } catch (Exception e) { log.error("X:"+X+ "||Y:"+Y,e); } return targetImage; } / * 获取目标区域 * * @param x 随机切图坐标x轴位置 * @param y 随机切图坐标y轴位置 * @param targetWidth 切图后目标宽度 * @param targetHeight 切图后目标高度 * @param ois 源文件输入流 * @return * @throws Exception */ private static BufferedImage getTargetArea(int x, int y, int targetWidth, int targetHeight, InputStream ois, String filetype) throws Exception { Iterator
imageReaderList = ImageIO.getImageReadersByFormatName(filetype); ImageReader imageReader = imageReaderList.next(); // 获取图片流 ImageInputStream iis = ImageIO.createImageInputStream(ois); // 输入源中的图像将只按顺序读取 imageReader.setInput(iis, true); ImageReadParam param = imageReader.getDefaultReadParam(); Rectangle rec = new Rectangle(x, y, targetWidth, targetHeight); param.setSourceRegion(rec); BufferedImage targetImage = imageReader.read(0, param); return targetImage; } / * 生成图像矩阵 * * @param * @return * @throws Exception */ private static int[][] getData(BufferedImage bimg) throws Exception { int[][] data = new int[bimg.getWidth()][bimg.getHeight()]; for (int i = 0; i < bimg.getWidth(); i++) { for (int j = 0; j < bimg.getHeight(); j++) { data[i][j] = bimg.getRGB(i, j); } } return data; } / * 随机生成抠图坐标 */ private static void generateCutoutCoordinates() { Random random = new Random(); int widthDifference = ORI_WIDTH - WIDTH; int heightDifference = ORI_HEIGHT - HEIGHT; if (widthDifference <= 0) { X = 5; } else { X = random.nextInt(ORI_WIDTH - WIDTH); if (X < WIDTH) {/*@herb 解决切图相对位置问题*/ X = WIDTH; } } if (heightDifference <= 0) { Y = 5; } else { Y = random.nextInt(ORI_HEIGHT - HEIGHT); } NumberFormat numberFormat = NumberFormat.getInstance(); numberFormat.setMaximumFractionDigits(2); xPercent = Float.parseFloat(numberFormat.format((float) X / (float) ORI_WIDTH)); yPercent = Float.parseFloat(numberFormat.format((float) Y / (float) ORI_HEIGHT)); } }
- controller类
package com.sikong.ms.web.controller; import com.google.common.collect.Maps; import com.sikong.hexuan.entity.welfare.WelEmployee; import com.sikong.ms.common.auth.shiro.UsernamePasswordToken; import com.sikong.ms.common.cache.jedis.JedisConfig; import com.sikong.ms.common.cache.jedis.JedisUtils; import com.sikong.ms.common.captcha.validate.VerifyImageUtil; import com.sikong.ms.common.util.Digests; import com.sikong.ms.common.util.FileUtil; import com.sikong.ms.web.service.WelEmployeeService; import com.sikong.ms.web.shiro.AccountAuthorizationRealm; import com.sikong.ms.web.shiro.CacheUtils; import com.sikong.ms.web.shiro.ValidateCache; import com.sikong.ms.web.utils.NumberUtils; import com.sikong.ms.web.utils.SendMessageUtil; import lombok.extern.slf4j.Slf4j; import net.sf.json.JSONObject; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.lang.StringUtils; import org.apache.shiro.SecurityUtils; import org.apache.shiro.authc.IncorrectCredentialsException; import org.apache.shiro.authc.UnknownAccountException; import org.apache.shiro.session.InvalidSessionException; import org.apache.shiro.session.Session; import org.apache.shiro.subject.Subject; import org.springframework.core.io.ClassPathResource; import org.springframework.stereotype.Controller; import org.springframework.util.Base64Utils; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import java.io.*; import java.net.JarURLConnection; import java.net.MalformedURLException; import java.net.URL; import java.net.URLDecoder; import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.zip.ZipEntry; / 1. Created by yansheng on 2014/6/29. */ @Slf4j @Controller @RequestMapping("/validate") public class ValidateController { @Resource private WelEmployeeService employeeService; / * 生成验证码 * * @return */ @RequestMapping(value = "/init") @ResponseBody public JSONObject init() throws IOException { JSONObject object = new JSONObject(); /*redis实现:使用base64编码转化成字符串处理*/ // List
imgList = JedisUtils.getList(JedisConfig.KEY_VALIDATE_IMG); // List
tpllist = JedisUtils.getList(JedisConfig.KEY_VALIDATE_TPL); // if (null == imgList || imgList.size() < 1 || tpllist == null || tpllist.size() < 1) { // imgList = new ArrayList
(); // tpllist = new ArrayList
(); // initValidateResources(imgList,tpllist); // JedisUtils.setList(JedisConfig.KEY_VALIDATE_IMG,imgList,JedisConfig.JEDIS_EXPIRE*3); // JedisUtils.setList(JedisConfig.KEY_VALIDATE_TPL,tpllist,JedisConfig.JEDIS_EXPIRE*3); // } /*本地缓存实现*/ List
imgList = ValidateCache.get(JedisConfig.KEY_VALIDATE_IMG); List
tpllist = ValidateCache.get(JedisConfig.KEY_VALIDATE_TPL); if (null == imgList || imgList.size() < 1 || tpllist == null || tpllist.size() < 1) { imgList = new ArrayList
(); tpllist = new ArrayList
(); initValidateResources(imgList,tpllist); ValidateCache.set(JedisConfig.KEY_VALIDATE_IMG,imgList); ValidateCache.set(JedisConfig.KEY_VALIDATE_TPL,tpllist); } byte[] targetIS = null; byte[] templateIS = null; Random ra = new Random(); if (null != imgList){ int rd = ra.nextInt(imgList.size()); targetIS = imgList.get(rd); } if (null != tpllist){ int rd = ra.nextInt(tpllist.size()); templateIS = tpllist.get(rd); } Map
pictureMap = null; try { pictureMap = VerifyImageUtil.pictureTemplatesCut(templateIS,targetIS , "png", "jpg"); String newImage = Base64Utils.encodeToString((byte[]) pictureMap.get("newImage")); String sourceImage = Base64Utils.encodeToString((byte[]) pictureMap.get("oriCopyImage")); int X = (int) pictureMap.get("X"); int Y = (int) pictureMap.get("Y"); object.put("newImage", newImage); object.put("sourceImage", sourceImage); //object.put("X", X); object.put("Y", Y); String token = UUID.randomUUID().toString().replaceAll("-", ""); Map
tokenObj = new HashMap
(); tokenObj.put("token", token); tokenObj.put("X", X); tokenObj.put("Y", Y); //token 保存2分钟 JedisUtils.setObjectMap(JedisConfig.KEY_VALIDATE_TOKEN + ":" + token, tokenObj, ); object.put("token", token); } catch (Exception e) { log.error("",e); } return object; } / * 初始化验证图形生成资源 * @param imgList * @param tpllist */ private void initValidateResources(List
imgList, List
tpllist) throws IOException { /*加载验证原图*/ String target = URLDecoder.decode(ValidateController.class.getClassLoader().getResource("static/image/validate/targets").getPath(),"UTF-8"); byte[] targetIS = null; byte[] templateIS = null; if (target.indexOf("!/") != -1) {//jar包 String jarPath = "jar:" + target; log.debug(jarPath); URL jarURL = new URL(jarPath); JarURLConnection jarCon = (JarURLConnection) jarURL.openConnection(); JarFile jarFile = jarCon.getJarFile(); Enumeration
jarEntrys = jarFile.entries(); while (jarEntrys.hasMoreElements()) { JarEntry entry = jarEntrys.nextElement(); String name = entry.getName(); if (name.startsWith("static/image/validate/targets") && !name.equals("static/image/validate/targets/") && (name.endsWith(".jpg") || name.endsWith(".png"))) { log.debug("targets=" + name); InputStream isTemplates = jarFile.getInputStream(entry); targetIS = IOUtils.toByteArray(jarFile.getInputStream(entry)); imgList.add(targetIS); } else if (name.startsWith("static/image/validate/templates") && !name.equals("static/image/validate/templates/") && (name.endsWith(".jpg") || name.endsWith(".png"))) { log.debug("templates=" + name); InputStream isTemplates = jarFile.getInputStream(entry); templateIS = IOUtils.toByteArray(jarFile.getInputStream(entry)); tpllist.add(templateIS); } } } else { File targetBaseFile = new File(target); if (null != targetBaseFile) { File[] fs = targetBaseFile.listFiles(); // Random ra = new Random(); // if (null != fs && fs.length > 0) { // int random = ra.nextInt(fs.length); // targetIS = IOUtils.toByteArray(new FileInputStream(fs[random])); // } for (File f : fs){ targetIS = IOUtils.toByteArray(new FileInputStream(f)); imgList.add(targetIS); } } /*加载切图模板*/ String template = URLDecoder.decode(ValidateController.class.getClassLoader().getResource("static/image/validate/templates").getFile(),"UTF-8"); File templateBaseFile = new File(template); if (null != templateBaseFile) { File[] fs = templateBaseFile.listFiles(); // Random ra = new Random(); // if (null != fs && fs.length > 0) { // int random = ra.nextInt(fs.length); // templateIS = IOUtils.toByteArray(new FileInputStream(fs[random])); // } for (File f : fs){ templateIS = IOUtils.toByteArray(new FileInputStream(f)); tpllist.add(templateIS); } } } log.info("initValidateResources:template size:" + tpllist.size() + "target size:" + imgList.size()); } / * 验证方法 (有验证码的方法提交,有时候也可以带上验证参数,做后端二次验证) * * @return */ @RequestMapping(value = "check",method = RequestMethod.POST) @ResponseBody public boolean check(String token, int X, int Y) { JSONObject message = new JSONObject(); message.put("code", 2); message.put("massage", "验证不通过,请重试!"); if (null == token || token.trim().length() < 1) { message.put("code", 0); message.put("massage", "请求参数错误:token为空!"); } Map
tokenObj = JedisUtils.getObjectMap(JedisConfig.KEY_VALIDATE_TOKEN + ":" + token); if (null == tokenObj) { message.put("code", -1); message.put("massage", "验证码超期,请重新请求!"); } else { int sX = (Integer) tokenObj.get("X"); int sY = (Integer) tokenObj.get("Y"); if (sY != Y) { message.put("code", 0); message.put("massage", "请求参数错误:位置信息不正确!"); } else { if (Math.abs(sX - X) <= 2) { message.put("code", 1); message.put("massage", "验证通过!"); } else { message.put("code", 2); message.put("massage", "验证不通过,请重试!"); } } } if (message.get("code")==1) { return true; } else { return false; } } / * 根据手机号查询用户是否存在 */ @RequestMapping("/checkUserIsHave") @ResponseBody public String checkUserIsHave( @RequestParam(required = false, value = "mobile") String mobile) { String isHave = "true"; WelEmployee welEmployee = new WelEmployee(); if (StringUtils.isNotEmpty(mobile)) { welEmployee.setMobile(mobile); } WelEmployee employee = employeeService.findWelEmployee(welEmployee); if (employee == null) { isHave = "false"; } return isHave; } / * 获取手机验证码 */ @RequestMapping(value = "/getMobileCode", method = RequestMethod.POST) @ResponseBody public Map
getMobileCode( @RequestParam(required =true, value = "account") String account) { Map
map = Maps.newHashMap(); try { Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); session.setAttribute("recordTime", System.currentTimeMillis());//设置当前时间点 log.debug("当前时间戳==" + System.currentTimeMillis()); Integer valid = NumberUtils.getRandomInt(99999); System.out.println(valid); session.setAttribute("mobile", account); session.setAttribute("validCode", valid);//验证码 SendMessageUtil sms = new SendMessageUtil();//发送短信 String str = sms.sendSms(account, " 验证码为 "+valid+",请在页面中输入以完成验证。"); map.put("success", "true"); map.put("message", "一分钟后可重新获取"); } catch (InvalidSessionException e) { log.error("获取验证码失败", e); map.put("success", "false"); map.put("message", "获取验证码失败!"); return map; } return map; } / * 校验输入的短信验证码是否正确 */ @RequestMapping(value = "/checkMobileCode", method = RequestMethod.POST) @ResponseBody public Map
checkMobileCode( @RequestParam(required =true, value = "bound") String bound) { bound = bound.trim(); Subject subject = SecurityUtils.getSubject(); Session session = subject.getSession(); Map
map = Maps.newHashMap(); Object code = session.getAttribute("validCode");//发送的验证码 Long recordTime = (Long) session.getAttribute("recordTime");//发送验证码的时候设置的时间点 if (bound == "") { map.put("success", "false"); map.put("message", "验证码不能为空"); return map; } else if (code == null || recordTime == null){ map.put("success", "false"); map.put("message", "未获取验证码"); return map; } Long now = System.currentTimeMillis(); log.debug("1时间==" + (now)); log.debug("2时间==" + (recordTime)); log.debug("记录时间==" + (now - recordTime)); if (!bound.equals(code.toString())) { map.put("success", "false"); map.put("message", "验证码错误"); } else if ((now - recordTime) > 65000) { map.put("success", "false"); map.put("message", "验证码已经失效"); } else { map.put("success", "true"); } return map; } / * 验证密码是否正确 */ @RequestMapping("/checkPassword") @ResponseBody public Map
checkUserIsHave( @RequestParam(required = false, value = "password") String password, @RequestParam(required = false, value = "employeeId") String employeeId ) { Map
map = Maps.newHashMap(); map.put("success","true"); WelEmployee welEmployee=employeeService.findWelEmployeeByEmployeeId(employeeId); String passwordOld=welEmployee.getPassword(); boolean res= Digests.validatePassword(password,passwordOld); if(!res){ map.put("success","false"); } return map; } public static void main(String[] args) { String stream = ValidateController.class.getClassLoader().getResource("static/image/validate/").getFile(); File validateBaseFile = new File(stream); File vf = null; if (null != validateBaseFile) { File[] fs = validateBaseFile.listFiles(); Random ra = new Random(); if (null != fs && fs.length > 0) { int random = ra.nextInt(fs.length); vf = fs[random]; } } System.out.println(vf.getName()); } }
- freemarker前端实现
<#macro imgValidate> <#---->
→
向右滑动滑块填充拼图
刷新
<#--
--> <#--
-->
参考
发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/219049.html原文链接:https://javaforall.net
