第一步,准备一个可以生成验证码的类或者jar包,我这里就用工具类了,网上随便找的一个工具类

/*** 生成图片验证码的工具类*/
public class VerifyCode {private int w = 70;private int h = 35;private Random r = new Random();// {"宋体", "华文楷体", "黑体", "华文新魏", "华文隶书", "微软雅黑", "楷体_GB2312"}private String[] fontNames  = {"宋体", "华文楷体", "黑体", "微软雅黑", "楷体_GB2312"};//可选字符private String codes  = "23456789abcdefghjkmnopqrstuvwxyzABCDEFGHJKMNPQRSTUVWXYZ";//背景色private Color bgColor  = new Color(255, 255, 255);private String text ;//生成随机的颜色private Color randomColor () {int red = r.nextInt(150);int green = r.nextInt(150);int blue = r.nextInt(150);return new Color(red, green, blue);}//生成随机字体private Font randomFont () {int index = r.nextInt(fontNames.length);String fontName = fontNames[index];int style = r.nextInt(4);  //生成随机样式,0:无样式,1:粗体,2:斜体,3:粗体+斜体int size = r.nextInt(5) + 24; //生成随机字号return new Font(fontName, style, size);}//画干扰线private void drawLine (BufferedImage image) {int num  = 3; //总共画三条干扰线Graphics2D g2 = (Graphics2D)image.getGraphics();for(int i = 0; i < num; i++) { //生成两个点的左边,即4个值int x1 = r.nextInt(w);int y1 = r.nextInt(h);int x2 = r.nextInt(w);int y2 = r.nextInt(h);g2.setStroke(new BasicStroke(1.5F));g2.setColor(Color.BLUE);   //设置干扰线颜色为蓝色g2.drawLine(x1, y1, x2, y2);}}//随机生成一个字符private char randomChar () {int index = r.nextInt(codes.length());return codes.charAt(index);}//创建BufferedImageprivate BufferedImage createImage () {BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);Graphics2D g2 = (Graphics2D)image.getGraphics();g2.setColor(this.bgColor);g2.fillRect(0, 0, w, h);return image;}public BufferedImage getImage () {BufferedImage image = createImage(); //创建图片缓冲区Graphics2D g2 = (Graphics2D)image.getGraphics();//得到绘制环境,画笔StringBuilder sb = new StringBuilder();//用来装载生成的验证码文本// 向图片中画4个字符for(int i = 0; i < 4; i++)  {String s = randomChar() + "";   //随机生成一个字符sb.append(s);float x = i * 1.0F * w / 4; //设置当前字符的x轴坐标g2.setFont(randomFont());  //设置随机字体g2.setColor(randomColor()); //设置随机颜色g2.drawString(s, x, h-5);  //画图}this.text = sb.toString();  //把生成的字符串赋给this.textdrawLine(image); //添加干扰线return image;}//返回验证码图片上的文本public String getText () {return text;}//保存图片到指定的输出流public static void output (BufferedImage image, OutputStream out)throws IOException {ImageIO.write(image, "JPEG", out);}
}

第二步,写个请求接口,用以获取验证码

/*** 验证码的controller*/
@RestController
public class VerifyCodeController {/*** 获取验证码** @param request* @param response* @throws IOException*/@GetMapping("/verifyCode/getVerifyCode")public void getVerifyCode(HttpServletRequest request, HttpServletResponse response) throws IOException {VerifyCode verifyCode = new VerifyCode();//生成图片BufferedImage image = verifyCode.getImage();//获取图片上的文本String text = verifyCode.getText();//把验证码的文本保存到session中,用以校验前端输入的验证码是否正确request.getSession().setAttribute("VERIFY_CODE", text);System.out.println("request.getSession().getAttribute(\"VERIFY_CODE\") = " + request.getSession().getAttribute("VERIFY_CODE"));//把生成的图片验证码响应给前端 客户端VerifyCode.output(image, response.getOutputStream());}
}

这里的代码逻辑就是:调用方法生成验证码,然后保存在 session 中,并通过流响应给前端。有的小伙伴不懂了,为什么要保存在 session 中呢,那是因为需要和前端传递过来的验证码进行比较。

来看结果:

此时验证码已经成功返回了。

接下来需要写一个验证码的过滤器,来验证验证码是否正确:

/*** 验证码的过滤器*/
@Component//注入到Spring容器中
public class VerificationCodeFilter extends GenericFilter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {/*** 强转为 ServletRequest和ServletResponse的子接口:*      HttpServletRequest和HttpServletResponse*/HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse resp = (HttpServletResponse) response;//如果是post请求,并且路径是 login 再进行校验,否则放行if ("POST".equals(req.getMethod()) && "/login".equals(req.getServletPath())) {System.out.println("VerificationCodeFilter-VERIFY_CODE = " + req.getSession().getAttribute("VERIFY_CODE"));//获取 session 中的验证码字符串String verifyCode = (String) req.getSession().getAttribute("VERIFY_CODE");//获取客户端传递过来的验证码String vc = req.getParameter("verifyCode");/*** 如果 客户端传递过来的验证码*   为"" 为 null 和session的值不一致 视为 验证码错误*/if (vc == null ||"".equals(vc) ||  !vc.toLowerCase().equals(verifyCode.toLowerCase())) {//设置响应头 要不然会出现乱码情况resp.setHeader("Content-Type", "text/html;charset=utf-8");//要往前端返回的数据/抛出异常} else {//验证码正确//让过滤器往下执行chain.doFilter(request, response);}} else {//让过滤器往下执行chain.doFilter(request, response);}}
}

上面代码的逻辑:如果请求路径是 `/login` 并且请求方式是 `POST` 的话,再去校验,然后判断前端传递过来的验证码 是否为空、是否为null、验证码是否正确。条件满足其一就返回错误信息。

接下来就是 SpringSecurity 的配置类了:

/*** SpringSecurity 的配置类*/
@Configuration
@EnableWebSecurity//开启web安全
public class SecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate VerificationCodeFilter verificationCodeFilter;@Overrideprotected void configure(HttpSecurity http) throws Exception {/*** 在 UsernamePasswordAuthenticationFilter 执行前,执行校验验证码的逻辑* 如果验证码输入错误,那就不用再继续接下来的流程了*///所有请求都需要登录校验http.authorizeRequests()/*** 注意代码中配置的三条规则的顺序非常重要,和 Shiro 类似,Spring Security* 在匹配的时候也是按照从上往下的顺序来匹配,一旦匹配到了就不继续匹配了,* 「所以拦截规则的顺序不能写错」。*/.antMatchers("/login", "/verifyCode/getVerifyCode").permitAll()//其余所有请求都需要认证.anyRequest().authenticated().and()//在 UsernamePasswordAuthenticationFilter 过滤器前添加.addFilterBefore(verificationCodeFilter, UsernamePasswordAuthenticationFilter.class);//禁用csrfhttp.csrf().disable();//允许跨域http.cors();}
}

接下来测试,登录就必须传验证码了,如果验证码不传或者传错,就会报错:

登录成功的情况:

现在就到前端 Vue了:

    <el-form-item label="验证码" prop="password"><el-input v-model="form.verifyCode" style="width: 250px;" placeholder="请输入验证码"></el-input><img title="点击更换验证码" :src="vcURL" @click="updateVcURL" alt=""></el-form-item>

vcURL:

//验证码的请求地址
vcURL: 'http://ip:port/path?time=' + new Date().getTime(),

点图片更换验证码的方法:

      //更换验证码  利用了只要变量的值更改,标签的值就会更改的特点,实现了更换验证码updateVcURL() {// console.info("new Date()", new Date().getTime());this.vcURL = "http://ip:port/path?time=" + new Date().getTime();}

使用获取当前时间戳的方式实现。只要变量的值更改,它就会重新发送一个请求请求验证码

SpringSecurity+Vue:实现添加登录图片验证码相关推荐

  1. html登录图片验证码的实现

    流程:验证码图片由服务器的java后端生成,前端向后端请求图片验证码,项目工程使用了springboot框架 生成图片验证码的工具类: package com.main.activity.verify ...

  2. Day239.RBAC模式、动态加载用户权限资源规则数据规则、【记住我】注销多次登录图片验证码session验证码验证功能 -springsecurity-jwt-oauth2

    1.RBAC权限管理模型 一.RBAC权限模型简介 RBAC权限模型(Role-Based Access Control)即:基于角色的权限控制.模型中有几个关键的术语: 用户:系统接口及功能访问的操 ...

  3. Vue+Spring Boot实现图片验证码、邮箱验证码以及Cookie记住我功能(前后端代码详解)

    Vue实现图片验证码.邮箱验证码以及Cookie记住我功能 前言 图片验证码实现 Vue前端实现 Spring Boot后端实现 邮箱验证码实现 Vue前端实现 Spring Boot后端实现 Coo ...

  4. Vue中添加背景图片

    往一个div中添加背景图片 bgImg:为图片地址 希望能帮到你!!

  5. PHP生成登录图片验证码

    很久之前写的 感觉登录还挺常用 记录一下. public function makeLoginCodeAction() //生成登录页的验证码 {Header("Content-type: ...

  6. VUE(10)--添加背景图片以及背景图片自适应

    背景图片地址不能直接写在标签里面,要用data绑定 背景图的地址要加require 背景图要设置height属性 <div :style="bgImg"> </d ...

  7. 登录功能图片验证码的实现

    首先从网上下载一个生成验证码的Servlet: package com.train.controller;import java.awt.Color; import java.awt.Font; im ...

  8. python 登陆网站图片验证,用python登录带弱图片验证码的网站

    上一篇介绍了使用python模拟登陆网站,但是登陆的网站都是直接输入账号及密码进行登陆,现在很多网站为了加强用户安全性和提高反爬虫机制都会有包括字符.图片.手机验证等等各式各样的验证码.图片验证码就是 ...

  9. Spring Boot整合Shiro + JSP教程(用户认证,权限管理,图片验证码)

    在此首先感谢**编程不良人**up主提供的视频教程 代码都是跟着up的视频敲的,遇到的一些问题也是通过CSDN博主提供的教程解决的,在此也感谢那些提供bug解决方案的前辈们~ 项目完整代码已经发布到g ...

最新文章

  1. 看看那些双车中接力装置
  2. PHPExcel常用方法汇总
  3. python重新加载模块_jupyter实现重新加载模块
  4. python之_init_函数的简介
  5. mongodb适用于_适用于MongoDB和Mongometer的SpiderMonkey至V8
  6. Xuggler开发教程
  7. python3 递归
  8. Kotlin学习笔记18 反射Part2
  9. 大学计算机基础实训指导第四版,大学计算机基础:学习指导与实训篇(第4版)...
  10. Levenshtein编辑距离C++实现
  11. mac 配置apache
  12. HTTP中的URL长度限制
  13. MeasureSpec介绍
  14. 锁定计算机密码如何取消,如何取消笔记本电脑硬盘密码锁?
  15. python实现整数反转
  16. 如何申请小程序账号及上线一个体验版小程序
  17. 【小程序】rpx(responsive pixel)自适应像素浅析
  18. Windows下安装Tensorflow-Slim(待续)
  19. trans系列是sci几区_sci怎么看几区
  20. 银行测试(7)-支付测试

热门文章

  1. IOS H5免签绿标 webclip
  2. python新手代码大全.pdf,python新手代码及作用
  3. 异常处理——NullPointerException
  4. 掌上实验室V8系列教程(八)ADC模数转换
  5. 2022.09 青少年Python等级考试(六级) 编程题部分
  6. 其他机器的访问mysql_解决MySQL其他机器连接不上的问题
  7. zai~~myGODDDD
  8. 如何看待二手服务器?买个二手服务器划算吗?
  9. ofdm系统matlab仿真论文,基于MATLAB的OFDM仿真(SIMULINK仿真)
  10. 数据中心SDN网络、VXLAN、虚拟化之间的关系和概念