标签分类
技术文章
当前位置:主页 > 计算机编程 > java > SpringBoot实现前端验证码图片生成和校验

SpringBoot实现前端验证码图片生成和校验的实例讲解

  • 发布时间:
  • 作者:码农之家原创
  • 点击:100

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

这篇文章主要知识点是关于SpringBoot,验证码,SpringBoot实现前端验证码图片生成和校验,springboot控制层图片验证码生成 的内容,如果大家想对相关知识点有系统深入的学习,可以参阅以下电子书

一步一步学Spring Boot 2
  • 类型:微服务项目实战大小:72.04 MB格式:PDF出版:清华大学出版社作者:黄文毅
立即下载

更多相关的学习资源可以参阅 程序设计电子书Java电子书、等栏目。

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

1.效果

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

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

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控制层图片验证码生成

本次博客记录项目中一个图片验证码的实现,虽然不是很复杂,但好记性不如烂笔头,谨记!

package com.zl.util; 
 
import java.awt.Color; 
import java.awt.Font; 
import java.awt.Graphics; 
import java.awt.image.BufferedImage; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.OutputStream; 
import java.util.Random; 
 
import javax.imageio.ImageIO; 
 
/** 
 * @author ZZC 
 * @date 2017年11月6日 
 * @param 
 * @desc 图形验证码生成 
 * 
 */ 
public class VerifyUtil { 
 // 验证码字符集 
  private static final char[] chars = {  
   '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',  
   'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 
   'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', 
   'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',  
   'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'}; 
  // 字符数量 
  private static final int SIZE = 4; 
  // 干扰线数量 
  private static final int LINES = 5; 
  // 宽度 
  private static final int WIDTH = 80; 
  // 高度 
  private static final int HEIGHT = 40; 
  // 字体大小 
  private static final int FONT_SIZE = 30; 
 
  /** 
   * 生成随机验证码及图片 
   * Object[0]:验证码字符串; 
   * Object[1]:验证码图片。 
   */ 
  public static Object[] createImage() { 
   StringBuffer sb = new StringBuffer(); 
   // 1.创建空白图片 
   BufferedImage image = new BufferedImage( 
     WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB); 
   // 2.获取图片画笔 
   Graphics graphic = image.getGraphics(); 
   // 3.设置画笔颜色 
   graphic.setColor(Color.LIGHT_GRAY); 
   // 4.绘制矩形背景 
   graphic.fillRect(0, 0, WIDTH, HEIGHT); 
   // 5.画随机字符 
   Random ran = new Random(); 
   for (int i = 0; i <SIZE; i++) { 
    // 取随机字符索引 
    int n = ran.nextInt(chars.length); 
    // 设置随机颜色 
    graphic.setColor(getRandomColor()); 
    // 设置字体大小 
    graphic.setFont(new Font( 
      null, Font.BOLD + Font.ITALIC, FONT_SIZE)); 
    // 画字符 
    graphic.drawString( 
      chars[n] + "", i * WIDTH / SIZE, HEIGHT*2/3); 
    // 记录字符 
    sb.append(chars[n]); 
   } 
   // 6.画干扰线 
   for (int i = 0; i < LINES; i++) { 
    // 设置随机颜色 
    graphic.setColor(getRandomColor()); 
    // 随机画线 
    graphic.drawLine(ran.nextInt(WIDTH), ran.nextInt(HEIGHT), 
      ran.nextInt(WIDTH), ran.nextInt(HEIGHT)); 
   } 
   // 7.返回验证码和图片 
   return new Object[]{sb.toString(), image}; 
  } 
 
  /** 
   * 随机取色 
   */ 
  public static Color getRandomColor() { 
   Random ran = new Random(); 
   Color color = new Color(ran.nextInt(256),  
     ran.nextInt(256), ran.nextInt(256)); 
   return color; 
  } 
 
  public static void main(String[] args) throws IOException { 
   Object[] objs = createImage(); 
   BufferedImage image = (BufferedImage) objs[1]; 
   OutputStream os = new FileOutputStream("d:/1.png"); 
   ImageIO.write(image, "png", os); 
   os.close(); 
  } 
} 

controller层

/** 
  * @author ZZC 
  * @date 2017年11月6日 
  * @param 
  * @desc 图形验证码生成方法 
  * 
  */ 
 @RequestMapping("/valicode") 
 public void valicode(HttpServletResponse response,HttpSession session) throws Exception{ 
  //利用图片工具生成图片 
  //第一个参数是生成的验证码,第二个参数是生成的图片 
  Object[] objs = VerifyUtil.createImage(); 
  //将验证码存入Session 
  session.setAttribute("imageCode",objs[0]); 
   
  //将图片输出给浏览器 
  BufferedImage image = (BufferedImage) objs[1]; 
  response.setContentType("image/png"); 
  OutputStream os = response.getOutputStream(); 
  ImageIO.write(image, "png", os); 
 } 

运行结果:

springboot控制层图片验证码生成

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

以上就是本次给大家分享的全部知识点内容总结,大家还可以在下方相关文章里找到儿童python编程入门书籍推、 解决axios.interceptors.respon、 vue项目中使用md5加密以及、 等java文章进一步学习,感谢大家的阅读和支持。

上一篇:SpringCloud实现SSO单点登录的用法及实例

下一篇:SpringCloud中Ribbon的使用方法

展开 +

收起 -

学习笔记
网友NO.959817

SpringBoot + SpringSecurity 短信验证码登录功能实现

实现原理 在之前的文章中,我们介绍了普通的帐号密码登录的方式: SpringBoot + Spring Security 基本使用及个性化登录配置。 但是现在还有一种常见的方式,就是直接通过手机短信验证码登录,这里就需要自己来做一些额外的工作了。 对SpringSecurity认证流程详解有一定了解的都知道,在帐号密码认证的过程中,涉及到了以下几个类:UsernamePasswordAuthenticationFilter(用于请求参数获取),UsernamePasswordAuthenticationToken(表示用户登录信息),ProviderManager(进行认证校验), 因为是通过的短信验证码登录,所以我们需要对请求的参数,认证过程,用户登录Token信息进行一定的重写。 当然验证码的过程我们应该放在最前面,如果图形验证码的实现一样。这样的做法的好处是:将验证码认证该过程解耦出来,让其他接口也可以使用到。 基本实现 验证码校验 短信验证码的功能实现,其实和图形验证码的原理是一样的。只不过一个是返回给前端一个图片,一个是给用户发送短消息,这里只需要去调用一下短信服务商的接口就好了。更多的原理可以参考 SpringBoot + SpringSecurity 实现图形验证码功能 AuthenticationToken 在使用帐号密码登录的时候,UsernamePasswordAuthenticationToken里面包含了用户的帐号,密码,以及其他的是否可用等状态信息。我们是通过……

网友NO.864208

SpringBoot使用JWT实现登录验证的方法示例

什么是JWT JSON Web Token(JWT)是一个开放的标准(RFC 7519),它定义了一个紧凑且自包含的方式,用于在各方之间以JSON对象安全地传输信息。这些信息可以通过数字签名进行验证和信任。可以使用秘密(使用HMAC算法)或使用RSA的公钥/私钥对来对JWT进行签名。 具体的jwt介绍可以查看官网的介绍:https://jwt.io/introduction/ jwt请求流程 引用官网的图片 中文介绍: 用户使用账号和面发出post请求; 服务器使用私钥创建一个jwt; 服务器返回这个jwt给浏览器; 浏览器将该jwt串在请求头中像服务器发送请求; 服务器验证该jwt; 返回响应的资源给浏览器 jwt组成 jwt含有三部分:头部(header)、载荷(payload)、签证(signature) 头部(header) 头部一般有两部分信息:声明类型、声明加密的算法(通常使用HMAC SHA256) 头部一般使用base64加密: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9 解密后: { "typ":"JWT", "alg":"HS256"} 载荷(payload) 该部分一般存放一些有效的信息。jwt的标准定义包含五个字段: iss:该JWT的签发者 sub: 该JWT所面向的用户 aud: 接收该JWT的一方 exp(expires): 什么时候过期,这里是一个Unix时间戳 iat(issued at): 在什么时候签发的 这个只是JWT的定义标准,不强制使用。另外自己也可以添加一些公开的不涉及安全的方面的信息。 签证(signature) JWT最后一个……

网友NO.778872

Springboot实现阿里云通信短信服务有关短信验证码的发送功能

前言 短信验证码是通过发送验证码到手机的一种有效的验证码系统。主要用于验证用户手机的合法性及敏感操作的身份验证。 现在市面上的短信服务平台有很多。大家在选择的时候未免会有些不好抉择。本人建议选择短信服务商应遵循以下几点: 服务商知名度高,业务流量大。(这样的平台可信度高) 服务稳定,不能经常宕机。(保证自身业务的流畅运行) 文档全面详细。(没文档怎么玩?) 最近的一个项目中,注册和修改密码时需要用到短信验证码校验手机号的功能。本人也是对比几家后,直接选择阿里云通信的短信服务。(本身项目服务器也是部署在阿里云上,但之前并不知道阿里云有短信服务,早知道阿里有的话就不会浪费时间找其他平台了)。废话不多说,下面直接开始短信验证服务教程。 准备 1.登录阿里云,开通阿里云通信短信服务。 2.申请accessKey 选择右上角accessKeys,创建一个access key 3.进入控制台,申请短信签名。这个作用就是用于短信前面“【】”里面的名称。输入时不需要带“【】” 注意申请规范,要不然审核不会过。符合规范的话一般一个小时左右就能通过了。 我这里的签名是“喝酒不骑马” 4.申请短信模版 模板类型选择验证码。注意,选择验证码后,模板替代变量只支持验证码作为变量,且……

网友NO.966766

springboot结合全局异常处理实现登录注册验证

在学校做一个校企合作项目,注册登录这一块需要对注册登录进行输入合法的服务器端验证,因为是前后端分离开发,所以要求返回JSON数据。 方法有很多,这觉得用全局异常处理比较容易上手 全局异常处理 首先来创建一个sprIngboot的web项目或模块,目录结构如下 实体类User.java @Datapublic class User { private String userName; private String passwold;} 实体类UserResult.java 把数据封装到这里返回到客户端 @Data@NoArgsConstructor@AllArgsConstructorpublic class UserResult { private int code; private String msg;} 接下来自定义异常,都继承自Exception UserNullException.java 当用户名为空抛出这个异常 public class UserNullException extends Exception{ public UserNullException() { super("用户名不能为空"); }} PasswoldNullException.java 当密码为空抛出这个异常 public class PasswoldNullException extends Exception { public PasswoldNullException() { super("密码不能为空"); }} UserNamePasswordNullException.java 当用户名和密码都为空抛出这个异常 public class UserNamePasswordNullException extends Exception { public UserNamePasswordNullException() { super("请输入用户名和密码"); }} UserNameValidationException.jva 当输入不符合要求的用户名时抛出此异常 public class UserNameValidationException extends Exception{ public UserNameValidationException() { super("请输入6到16位的数字或字母组合"); }} UserNam……

<
1
>

Copyright 2018-2019 xz577.com 码农之家

版权责任说明