SpringBoot实现前端验证码图片生成和校验,Ajax实现验证码的实时验证

3.获取验证码,产生验证码的页面又在另一个网址里,后台生成验证码图片

实现这里的图形验证码我是用的node里svg-captcha模块,可以全部支持字符和数字,全平台支持,用起来很简单。

PHP的图像处理功能强大,做一张验证码图片也是非常简单的,但是,在实现实时验证时,确遇到了一个难题:
我用nat123对我的电脑上的网站进行端口映射,实现了在外网访问,本来是采用cookie的方式用js对验证码进行验证,但是经检验发现nat123虽然使我的网站可以通过一个自定义的网址进行访问,但是产生验证码的php文件在网络上的位置竟然和其它页面不在一个域,经查询得知,因为输出图片的缘故,被作为缓存文件映射在了某个文件夹内,所以——其他页面在我的网址下,产生验证码的页面又在另一个网址里,所以它们的cookie不能共用,不管怎么设置path和domain都不管用,于是我只好采用session存储验证码了,因为session存在于服务器,也就是在我本地网址中都可以存取。
接下来是重头戏,之前只是粗略了解过ajax,对于它的用途和特性还是知道的,获取后台来的数据这个比较泛泛的概念具体的使用起来就不知道如何下手了。
首先,我分析了个例题的代码,用途是获取后台的一个文本文件的内容:

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

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

1.效果

图片 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即可。

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

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

1.安装

function getHTTPObject(){
  if(typedef XMLHttpRequest == "undefined")
    XMLHttpRequest = function(){
      try{ return new ActiveXObject("Msxml2.XMLHTTP.6.0");}
      catch(e){}
      try{ return new ActiveXObject("Msxml2.XMLHTTP.3.0");}
      catch(e){}
      try{ return new ActiveXObject("Msxml2.XMLHTTP");}
      catch(e){}
      return false;
    }
    return new XMLHttpRequest();
}
function getNewContent(){
  var request = getHTTPObject();
  if(request){
    request.open("GET","TEST.txt",true);
    request.onreadystateschange = function(){
      alert(request.responseText);
    }
  }else{
  alert("no support XMLHttpRequest!");
  }
}
cnpm i svg-captcha --save

其中的关键是:

2.在使用的地方导入

  request.open("GET","TEST.txt",true);
    request.onreadystateschange =function(){
      alert(request.responseText);
    }
var svgCaptcha = require('svg-captcha');

这三句指定了GET请求发向的页面和XMLHttpRequest对象送回响应的时候触发的处理函数,而数据正是通过request.responseText获取的。

3.获取验证码


3-1 安装 cookie-parser
,作用是将获取到的session保存到cookie,方便前端访问验证

可是我要获取的数据是后台php文件产生的验证码,怎么让后台发送验证码?
无论GET还是POST方式都是把数据发送到后台,ajax从哪里取回后台的数据呢?
百思不得其解之下,我又查询了另一本资料,找到一个示例:
其中XMLHttpRequest对象送回响应的处理语句是:

cnpm i cookie-parser --save

request.onreadystateschange=alertContent;
function alertContent(){
...
  alert(request.responseText);
...
}

3-2 使用 cookie-parser

请求的文件为check.php
其中有这么几句条件输出:

const cookieParase = require('cookie-parser');

app.use(cookieParase());
if($info){
  echo "你的用户名可以使用";
}else {
  echo "该用户名已被注册";
}

这样就可以在项目里使用cookie了

而运行实例效果图中赫然在静态页面弹出消息框,内容如check.php页面的输出!!!
也就是说ajax能请求到一个php页面的输出内容,于是,接下来简单多了,因为图片也是验证码页面的输出,所以不能直接ajax验证码页面,不然就把图片的数据也获取了。
新建一个php页面:

3-3 获取验证码

sission_start();
$code="";
if(!empty($_session['check']))$code=$_session['check'];
echo $code;
// 获取验证码
 getCaptcha(req, res, next){
  var captcha = svgCaptcha.create({ 
   // 翻转颜色 
   inverse: false, 
   // 字体大小 
   fontSize: 36, 
   // 噪声线条数 
   noise: 2, 
   // 宽度 
   width: 80, 
   // 高度 
   height: 30, 
  }); 
  // 保存到session,忽略大小写 
  req.session = captcha.text.toLowerCase(); 
  console.log(req.session); //0xtg 生成的验证码
  //保存到cookie 方便前端调用验证
  res.cookie('captcha', req.session); 
  res.setHeader('Content-Type', 'image/svg+xml');
  res.write(String(captcha.data));
  res.end();
 },

再在前端用ajax向这个页面GET一个请求,就能用request.responseText获取验证码了。
然后把验证过程封装在一定条件触发的函数里,即可实时验证。

做到这只是实现了生成验证码的功能,那么要访问呢?

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

4.编写后台路由

您可能感兴趣的文章:

  • asp.net
    ajax实现无刷新验证码
  • 基于Ajax用户名验证、服务条款加载、验证码生成的实现方法
  • Ajax实现带有验证码的局部刷新登录界面
  • Ajax和PHP正则表达式验证表单及验证码
  • PHP+Ajax验证码验证用户登录
  • thinkphp验证码的实现(form、ajax实现验证)
  • jsp+ajax实现的局部刷新较验验证码(onblur事件触发较验)
  • PHP生成各种常见验证码和Ajax验证过程
  • Ajax提交表单时验证码自动验证
    php后端验证码检测
  • 基于ajax实现验证码功能
// 获取验证码
router.get('/api/getCaptcha', function(req, res, next) {
 return api.getCaptcha(req, res, next);
})

当前端调用 /api/getCaptcha 这个接口的时候,返回验证码信息,是svg格式

5.前端访问

<img src="/api/getCaptcha" alt="captcha" >

图片 2

但是现在我们又有需求了,当点击这个验证码的时候,验证码会刷新

6.实现点击验证码刷新

更改一下刚刚验证码的结果,给他加一个外层a标签,并给他绑定一个点击事件,我这里用了
vue ,所以是 @click ,其他框架同理.

<a href="#" rel="external nofollow" @click="editCaptcha">
  <img src="/api/getCaptcha" alt="图片 3" ref="imgYzm">
</a>

点击事件 editCaptcha

editCaptcha () {
  this.$refs.imgYzm.src = '/api/getCaptcha?d='+Math.random()
},

这样就实现了点击验证码刷新的问题

7.前端验证验证码

刚刚我们在后台得到了验证码,但是前端要怎么验证呢?

记得在3-2的时候我们安装了 cookie-parser
,并且在3-3里将生成的session保存在cookie里,这里我们前端就可以通过访问这个cookie拿到验证码的值了。

图片 4

为什么要保存在cookie里?
因为后端生成的session我们前端是访问不到的,如果等访问到的话,那还谈什么安全性可言,所以保存一份在cookie里供前端访问。

let captcha = document.cookie.split('=')[1]
  if(this.yzm != captcha){
   return this.$message.warning('验证码错误')
  }

最后的前端输入账号密码验证码做登录验证等等我就不多概述了。具体思想就是这样。

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

您可能感兴趣的文章:

  • Nodejs中使用captchapng模块生成图片验证码
  • node.js
    WEB开发中图片验证码的实现方法