springboot实现验证码功能

转载自 : www.javaman.cn

1、编写工具类生成4位随机数

该工具类主要生成从0-9,a-z,A-Z范围内产生的4位随机数

/*** 产生4位随机字符串*/public static String getCheckCode() {String base = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";int size = base.length();Random r = new Random();StringBuffer sb = new StringBuffer();for (int i = 1; i <= 4; i++) {//产生0到size-1的随机值int index = r.nextInt(size);//在base字符串中获取下标为index的字符char c = base.charAt(index);//将c放入到StringBuffer中去sb.append(c);}return sb.toString();}
2、编写常量类

用户常量的绑定,所有的常量都可以在ConfigConsts中定义,方便管理。

import java.util.Arrays;
import java.util.List;public interface ConfigConsts {/*** 验证码存session*/String IMAGE_CODE_SESSION = "IMAGE_CODE";
}
3、获取验证码接口

这段代码的主要作用是为用户生成一个图片验证码,并将其显示在浏览器中。当调用该代码对应的URL时,服务器会创建一个包含随机验证码的图片,并将此验证码存储在用户的会话中,然后将该图片发送给用户的浏览器显示

     /*** 验证码*/@RequestMapping("/getImgCode")public void getImgCode(HttpServletRequest request, HttpServletResponse response) {int width = 80;int height = 30;BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);//获取画笔Graphics graphics = image.getGraphics();//设置画笔颜色为白色graphics.setColor(Color.white);//填充图片graphics.fillRect(0, 0, width, height);//设置画笔颜色为黑色graphics.setColor(Color.black);//设置字体的小大graphics.setFont(new Font("黑体", Font.BOLD, 24));//产生4个随机验证码String checkCode = CommonUtil.getCheckCode();//将验证码放入HttpSession中HttpSession session = request.getSession();session.setAttribute(ConfigConsts.IMAGE_CODE_SESSION, checkCode);//向图片上写入验证码graphics.drawString(checkCode, 15, 25);//将内存中的图片输出到浏览器try {response.setContentType("image/png");ImageIO.write(image, "PNG", response.getOutputStream());} catch (IOException e) {e.printStackTrace();}}
4、controller跳转到登录页

对“/loginPage”的GET请求,并将用户重定向到登录页面。当调用这个URL时,系统会返回一个名为"login"的视图(通常是一个HTML页面),这个视图通常用于显示登录表单,让用户输入用户名和密码等信息。

    /*** 跳转到登陆页面* @return 登陆页面*/@GetMapping("/loginPage")public String loginPage(){return "login";}
5、登录界面

在Web页面上实现一个图形验证码的输入功能

  1. HTML部分
    • 创建一个表单项,内部包含两列(使用layui的栅格系统)。
    • 在第一列中,有一个标签和一个文本输入框。标签用于显示一个验证码图标,输入框用于用户输入图形验证码。
    • 在第二列中,有一个图片元素用于显示图形验证码图片。
  2. JavaScript部分
    • 配置layui的静态资源路径和主入口模块。
    • 初始化时,调用getImgCode函数加载验证码图片,并渲染表单。
    • getImgCode函数通过Ajax请求从服务器获取验证码图片,并将其显示在页面上的图片元素中。

这段代码主要利用了layui框架来实现页面的布局和交互,同时通过JavaScript和Ajax实现与服务器的通信,以获取并显示图形验证码。

<div class="layui-form-item"><div class="layui-row"><div class="layui-col-xs7"><label class="layadmin-user-login-icon layui-icon layui-icon-vercode"></label><input type="text" name="code"  lay-verify="required" placeholder="图形验证码" class="layui-input"></div><div class="layui-col-xs5"><div style="margin-left: 10px;"><img id="codeImg" class="layadmin-user-login-codeimg"></div></div></div><script>layui.config({base: '/static/layuiadmin/' //静态资源所在路径}).extend({index: 'lib/index' //主入口模块}).use(['index', 'user'], function(){let $ = layui.$,form = layui.form;// 初始化getImgCode();form.render();}/*** 获取验证码*/function getImgCode() {let url = ctx + '/getImgCode';let xhr = new XMLHttpRequest();xhr.open('GET', url, true);xhr.responseType = "blob";xhr.onload = function() {if (this.status === 200) {let blob = this.response;document.getElementById("codeImg").src = window.URL.createObjectURL(blob);}}xhr.send();}</script>
6、验证码过滤

校验验证码的过滤器,基于Java的Spring框架。

  1. 该过滤器继承了OncePerRequestFilter,确保每次请求只被过滤一次。
  2. doFilterInternal方法中,它首先检查请求是否是登录请求(通过检查请求路径是否为"/login"以及请求方法是否为"POST")。
  3. 如果是登录请求,它会调用validate方法来校验验证码。
  4. validate方法从请求中获取验证码,然后与会话中存储的验证码进行比对。如果验证码不存在、为空或不匹配,将抛出异常。
  5. 如果验证码校验失败,过滤器会捕获异常,并向响应中写入错误信息(以JSON格式)。
  6. 如果请求不是登录请求,过滤器不会进行验证码校验,直接让请求继续向下执行(通过调用filterChain.doFilter)。
  7. 如果登录请求成功通过验证码校验,代码会继续执行后续的过滤器或处理器。
@Component
public class ValidateCodeFilter extends OncePerRequestFilter {@Overrideprotected void doFilterInternal(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, FilterChain filterChain) throws ServletException, IOException {// 登陆请求if ("/login".equals(httpServletRequest.getServletPath()) &&"POST".equalsIgnoreCase(httpServletRequest.getMethod())){try {validate(httpServletRequest);} catch (Exception exception) {httpServletResponse.setCharacterEncoding("utf-8");httpServletResponse.setContentType("application/json;charset=UTF-8");PrintWriter writer = httpServletResponse.getWriter();writer.write(JSON.toJSONString(Result.failure(exception.getMessage())));writer.flush();return;}}// 不是一个登录请求,不做校验 直接通过filterChain.doFilter(httpServletRequest, httpServletResponse);}private void validate(HttpServletRequest request) {String code = request.getParameter("code");if (StringUtils.isBlank(code)){throw new RuntimeException("验证码不能为空");}Object checkCode = request.getSession(false).getAttribute(ConfigConsts.IMAGE_CODE_SESSION);if (Objects.isNull(checkCode)) {throw new RuntimeException("验证码不存在");}if (!StringUtils.equalsIgnoreCase(code,checkCode.toString())) {throw new RuntimeException("验证码不匹配");}request.getSession(false).removeAttribute(ConfigConsts.IMAGE_CODE_SESSION);}
}
7、集成mysecurity

集成Spring Security的安全配置类,用于Web应用的安全性设置。

  1. 通过@EnableWebSecurity@Configuration注解,启用并配置Spring Security。
  2. 使用@EnableGlobalMethodSecurity(prePostEnabled = true)来启用全局方法级别的安全性,允许使用例如@PreAuthorize@PostAuthorize等注解。
  3. 定义了一个名为MySecurityConfig的配置类,该类继承自WebSecurityConfigurerAdapter,用于定制安全性设置。
  4. 通过@Autowired注入了一个名为validateCodeFilter的验证码过滤器实例。
  5. configure(HttpSecurity http)方法中,对应用的安全性进行了详细配置:
    • 允许所有人访问/loginPage/getImgCode这两个路径,不进行任何安全检查。
    • 对所有其他请求,需要用户进行身份验证(即需要登录后才能访问)。
    • 在用户名和密码验证过滤器之前,添加了一个自定义的验证码过滤器(validateCodeFilter),用于在登录过程中校验验证码。

这段代码的主要目的是增强Web应用的安全性,限制了只有经过身份验证的用户才能访问应用的受保护资源。

@Configuration
@EnableWebSecurity
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class MySecurityConfig extends WebSecurityConfigurerAdapter {@Autowiredprivate ValidateCodeFilter validateCodeFilter;@Overrideprotected void configure(HttpSecurity http) throws Exception {http.authorizeRequests()// 放过.antMatchers("/loginPage", "/getImgCode").permitAll().anyRequest().authenticated().and()// 过滤登录验证码.addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)}

运行结果如下:

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/179437.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

异步爬虫提速实践-在Scrapy中使用Aiohttp/Trio

在构建爬虫系统时&#xff0c;提高爬虫速度是一个关键问题。而使用异步爬虫技术可以显著提升爬取效率。在本文中&#xff0c;我将与大家分享如何在Scrapy中利用Aiohttp或Trio库实现异步爬取&#xff0c;以加快爬虫的速度。让我们开始吧&#xff01; 1. 安装所需的库 首先&…

C语言——数组转换

将的两行三列数组转换为三行两列的数组 #define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> int main() {int a[2][3]{{1,2,3},{4,5,6}};int b[3][2],i,j;for ( i 0; i <1; i){for ( j 0; j <2; j){printf("%5d",a[i][j]);b[j][i]a[i][j];}printf(&…

为第一个原生Spring5应用程序添加上Log4J日志框架!

&#x1f609;&#x1f609; 学习交流群&#xff1a; ✅✅1&#xff1a;这是孙哥suns给大家的福利&#xff01; ✨✨2&#xff1a;我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 &#x1f96d;&#x1f96d;3&#xff1a;QQ群&#xff1a;583783…

【.NET全栈】.net的微软API接口与.NET框架源码

文章目录 0 前言1 微软官方.net接口学习2 .NET框架源码总结 0 前言 如果浏览器打不开链接&#xff0c;换一个浏览器打开。 我是 打不开微软的链接&#xff0c;使用&#xff1a; 可以打开&#xff01;&#xff01;&#xff01; 1 微软官方.net接口学习 https://docs.microsoft…

如何写好产品软文?软文撰写指南!

针对某种产品写一篇软文&#xff0c;我们应该怎么构思&#xff0c;怎么提笔去写&#xff0c;怎么写得让用户认可我们的产品&#xff0c;并产生消费的冲动&#xff0c;这是需要讲究技巧的。 今天伯乐网络传媒来给大家分享三个步骤&#xff0c;教你轻轻松松撰写一篇爆文&#xf…

电子学会C/C++编程等级考试2022年03月(二级)真题解析

C/C++等级考试(1~8级)全部真题・点这里 第1题:温度统计 现有一段时间的温度数据,请统计指定温度出现的次数。 时间限制:1000 内存限制:65536输入 第一行一个整数n,表示温度数据的个数。(0 < n ≤ 200) 第二行n个整数,以空格分隔,每个整数表示一个温度,温度的范围大…

Opencv-C++笔记 (19) : 分水岭图像分割

文章目录 一、基于距离变换与分水岭的图像分割1、图像分割2、距离和变换与分水岭距离变换常见算法有两种分水岭变换常见的算法 3、距离变换API函数接口4、watershed 分水岭函数API接口步骤 5、代码 一、基于距离变换与分水岭的图像分割 1、图像分割 图像分割(Image Segmentat…

Android问题记录 - Unable to make field private final java.lang.String java.io.File.path accessible(持续更新)

文章目录 前言开发环境问题描述问题分析解决方案补充内容最后 前言 最近一个Flutter项目有新需求&#xff0c;开发时一直是在iOS设备上运行&#xff0c;花了几天做完后运行到Android设备测试&#xff0c;结果项目构建失败了。 开发环境 Flutter: 3.7.11Android Studio: 2022…

MySQL进阶知识:二

目录 视图 基本语法 视图的更新 视图的作用 存储过程 介绍 存储过程基本语法 存储过程的变量 系统变量 用户自定义变量 局部变量 存储过程的判断逻辑 存储过程的参数 存储过程中的流程控制 存储过程中的循环 while的基本语法 repeat的基本语法 loop的基本语法…

金山办公前端二面

1. react 和 vue的区别 还有jquery&#xff1f; &#xff08;1&#xff09; jquery 和 vue、react 的区别&#xff1a; vue 和 react : 数据和视图分离 以数据驱动视图&#xff0c;只关心数据变化 dom 操作被封装&#xff08;数据驱动&#xff09; jquery&#xff1a;依靠 do…

【问题解决!】OSError: [WinError 1455] 页面文件太小,无法完成操作。Error loading “c:\Anaconda3\lib

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 问题描述问题原因二、解决方法 问题描述 在使用pytorch跑深度学习的时候报错OSError: [WinError 1455] 页面文件太小&#xff0c;无法完成操作。Error loading “c…

系列七、事务

一、事务 1.1、概述 事务是数据库操作的基本单元&#xff0c;它是指逻辑上的一组操作&#xff0c;要么都成功&#xff0c;要么都失败。典型场景&#xff1a;转账&#xff0c;例如Jack给Rose转账1000元&#xff0c;转账成功&#xff1a;Jack账户的余额少1000元&#xff0c;Rose…

人脸识别经典网络-MTCNN(含Python源码实现)

人脸检测-mtcnn 本文参加新星计划人工智能赛道&#xff1a;https://bbs.csdn.net/topics/613989052 文章目录 人脸检测-mtcnn1. 人脸检测1.1 人脸检测概述1.2 人脸检测的难点1.3 人脸检测的应用场景 2. mtcnn2.1 mtcnn概述2.2 mtcnn的网络结构2.3 图像金字塔2.4 P-Net2.5 R-Ne…

戴尔科技推出全新96核Precision 7875塔式工作站

工作站行业一直是快节奏且充满惊喜的。在过去25年中,戴尔Precision一直处于行业前沿,帮助创作者、工程师、建筑师、研究人员等将想法变为现实,并对整个世界产生影响。工作站所发挥的作用至关重要,被视为化不可能为可能的必要工具。如今,人工智能(AI)和生成式AI(GenAI)的浪潮正在…

西南科技大学C++程序设计实验二(类与对象一)

C++最大的特点就是面向对象,掌握它的几种基本性质还是好理解的,可以看我C++专栏的期末速成,希望对你们学习C++有帮助。 一、实验目的 1.理解简单类的定义、说明与使用 2.理解类中不同属性数据成员的访问特点 3.理解构造函数、析构函数的作用 重点:掌握类的定义与实现,…

MPPT工作流程及算法和硬件的选择

MPPT算法选择 目前&#xff0c;MPPT算法有开路电压比率(离线)、短路电流比率(离线)、观察调节(在线)、极限追踪控制法(在线)。 在光伏控制系统中&#xff0c;因为日照、温度等条件的变化&#xff0c;光伏电池的输出功率也是在不断变化的&#xff0c;为保证使得光伏电池的输出功…

vue3中的customRef创建一个自定义的 ref对象

customRef 创建一个自定义的 ref&#xff0c;并对其依赖项跟踪和更新触发进行显式控制 小案例: 自定义 ref 实现 debounce <template><div style"font-size: 14px;"><input v-model"text" placeholder"搜索关键字"/><…

渗透测试考核--两层内网 cs windows socks5

这里考核为渗透 这里是网络拓扑图 这里记录一下 两台外网 两台内网 首先拿到C段 nmap进行扫描 外网1 nmap -p 80 172.16.17.2/24 主机存活 一般都是web服务入手 所以我们指定80端口 然后去查找开放的 最后获取到2个ip Nmap scan report for 172.16.17.177 Host is u…

如何高效批量生成条形码?

条形码作为商品、库存和信息管理的基础工具&#xff0c;扮演着至关重要的角色。为了满足用户对于高效、专业、多样化的条形码生成需求&#xff0c;我们推出了一款专业高效的在线条形码生成工具。 网址&#xff1a;https://www.1txm.com/ 多样化条形码支持 易条形支持多种常见…

评价体系如何构建?

本文将针对权重计算的一些常见问题进行说明&#xff1a;如组合赋权法的综合权重值如何计算&#xff1f;多层级权重如何计算&#xff1f;用多种方法计算得到的权重如何合并为综合权重用于之后的分析&#xff1f;常见的不同权重计算方法的搭配方式&#xff1f; 一、九种权重计算…