首页 > 编程 > Java > 正文

SpringBoot实现前端验证码图片生成和校验

2019-11-26 10:13:41
字体:
来源:转载
供稿:网友

SpringBoot下实现前端验证码图片的生成和校验,供大家参考,具体内容如下

1.效果

点击验证码可以获取新的验证码

2.原理

后台生成验证码图片,将图片传到前台。
后台在session中保存验证码内容。
前台输入验证码后传到后台在后台取出session中保存的验证码进行校验。

注意,验证码的明文是不能传送到前端的。前端内容都是透明的,不安全。验证码是用来防机器人并不是单单防人。如果把验证码明文传到前端很容易就会被破解。

3.图片生成

验证码生成工具类RandomValidateCodeUtil

public class RandomValidateCodeUtil { public static final String RANDOMCODEKEY= "RANDOMVALIDATECODEKEY";//放到session中的key private String randString = "0123456789";//随机产生只有数字的字符串 private String //private String randString = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生只有字母的字符串 //private String randString = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";//随机产生数字与字母组合的字符串 private int width = 95;// 图片宽 private int height = 25;// 图片高 private int lineSize = 40;// 干扰线数量 private int stringNum = 4;// 随机产生字符数量 private static final Logger logger = LoggerFactory.getLogger(RandomValidateCodeUtil.class); private Random random = new Random(); /**  * 获得字体  */ private Font getFont() {  return new Font("Fixedsys", Font.CENTER_BASELINE, 18); } /**  * 获得颜色  */ private Color getRandColor(int fc, int bc) {  if (fc > 255)   fc = 255;  if (bc > 255)   bc = 255;  int r = fc + random.nextInt(bc - fc - 16);  int g = fc + random.nextInt(bc - fc - 14);  int b = fc + random.nextInt(bc - fc - 18);  return new Color(r, g, b); } /**  * 生成随机图片  */ public void getRandcode(HttpServletRequest request, HttpServletResponse response) {  HttpSession session = request.getSession();  // BufferedImage类是具有缓冲区的Image类,Image类是用于描述图像信息的类  BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_BGR);  Graphics g = image.getGraphics();// 产生Image对象的Graphics对象,改对象可以在图像上进行各种绘制操作  g.fillRect(0, 0, width, height);//图片大小  g.setFont(new Font("Times New Roman", Font.ROMAN_BASELINE, 18));//字体大小  g.setColor(getRandColor(110, 133));//字体颜色  // 绘制干扰线  for (int i = 0; i <= lineSize; i++) {   drowLine(g);  }  // 绘制随机字符  String randomString = "";  for (int i = 1; i <= stringNum; i++) {   randomString = drowString(g, randomString, i);  }  logger.info(randomString);  //将生成的随机字符串保存到session中  session.removeAttribute(RANDOMCODEKEY);  session.setAttribute(RANDOMCODEKEY, randomString);  g.dispose();  try {   // 将内存中的图片通过流动形式输出到客户端   ImageIO.write(image, "JPEG", response.getOutputStream());  } catch (Exception e) {   logger.error("将内存中的图片通过流动形式输出到客户端失败>>>> ", e);  } } /**  * 绘制字符串  */ private String drowString(Graphics g, String randomString, int i) {  g.setFont(getFont());  g.setColor(new Color(random.nextInt(101), random.nextInt(111), random    .nextInt(121)));  String rand = String.valueOf(getRandomString(random.nextInt(randString    .length())));  randomString += rand;  g.translate(random.nextInt(3), random.nextInt(3));  g.drawString(rand, 13 * i, 16);  return randomString; } /**  * 绘制干扰线  */ private void drowLine(Graphics g) {  int x = random.nextInt(width);  int y = random.nextInt(height);  int xl = random.nextInt(13);  int yl = random.nextInt(15);  g.drawLine(x, y, x + xl, y + yl); } /**  * 获取随机的字符  */ public String getRandomString(int num) {  return String.valueOf(randString.charAt(num)); }}

在Controller调用生成验证码图片方法并将图片传到前端

/** * 生成验证码 */@RequestMapping(value = "/getVerify")public void getVerify(HttpServletRequest request, HttpServletResponse response) { try {  response.setContentType("image/jpeg");//设置相应类型,告诉浏览器输出的内容为图片  response.setHeader("Pragma", "No-cache");//设置响应头信息,告诉浏览器不要缓存此内容  response.setHeader("Cache-Control", "no-cache");  response.setDateHeader("Expire", 0);  RandomValidateCodeUtil randomValidateCode = new RandomValidateCodeUtil();  randomValidateCode.getRandcode(request, response);//输出验证码图片方法 } catch (Exception e) {  logger.error("获取验证码失败>>>> ", e); }}

前端获取验证码图片

html

<div class="row"> <div class="col-xs-6 pull_left">  <div class="form-group">   <input class="form-control" type="tel" id="verify_input" placeholder="请输入验证码" maxlength="4">  </div> </div> <div class="col-xs-6 pull_left">  <a href="javascript:void(0);" rel="external nofollow" title="点击更换验证码">   <img id="imgVerify" src="" alt="更换验证码" height="36" width="100%" onclick="getVerify(this);">  </a> </div></div>

js

//获取验证码function getVerify(obj){ obj.src = httpurl + "/sys/getVerify?"+Math.random();}

每次点击图片重新刷新验证码
界面初次加载时,调用getVerify()方法即可。

4.验证码验证

前端获取用户输入的验证码,传到后台进行验证。
后台验证代码

/** * 忘记密码页面校验验证码 */@RequestMapping(value = "/checkVerify", method = RequestMethod.POST, headers = "Accept=application/json")public boolean checkVerify(@RequestBody Map<String, Object> requestMap, HttpSession session) { try{  //从session中获取随机数  String inputStr = requestMap.get("inputStr").toString();  String random = (String) session.getAttribute("RANDOMVALIDATECODEKEY");  if (random == null) {   return false;  }  if (random.equals(inputStr)) {   return true;  } else {   return false;  } }catch (Exception e){  logger.error("验证码校验失败", e);  return false; }}

后台校验后,返给前端验证结果true或者false即可。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表