首页 > 其他分享 >springboot实现验证码功能

springboot实现验证码功能

时间:2023-11-27 20:44:21浏览次数:34  
标签:功能 请求 登录 验证码 校验 getImgCode new 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 {
    @Override
    protected 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 {
	@Autowired
    private ValidateCodeFilter validateCodeFilter;
    
    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.authorizeRequests()
                // 放过
                .antMatchers("/loginPage", "/getImgCode").permitAll()
                .anyRequest().authenticated()
                .and()
                // 过滤登录验证码
                .addFilterBefore(validateCodeFilter, UsernamePasswordAuthenticationFilter.class)
    }

运行结果如下:

image

标签:功能,请求,登录,验证码,校验,getImgCode,new,springboot
From: https://www.cnblogs.com/dalaba/p/17860409.html

相关文章

  • SpringBoot3基础知识梳理
    一、SpringBoot3介绍1.1SpringBoot3简介​ SpringBoot帮我们简单、快速地创建一个独立的、生产级别的Spring应用(说明:SpringBoot底层是Spring),大多数SpringBoot应用只需要编写少量配置即可快速整合Spring平台以及第三方技术。SpringBoot的主要目标是:为所有Spring开发......
  • springboot004网页时装购物系统-计算机毕业设计源码+LW文档
    1 背景介绍1.1 节标题2 国内外研究现状2.1 研究方向及进展随着电子科技的不断进步,现在购物不在是单一的线下购物形式,如外国的最大电商网站亚马逊(amazon),在世界的各个地方都有它的足迹。慢慢的在中国每一天的购物商品也在网上购物形成了一种固定的消费习惯。大部分选择......
  • 轻松实现海报换脸!相芯SDK海报换脸功能的简单集成方法(Android)
    相芯SDK的海报换脸功能是一种面部合成技术,允许用户将自己的脸部特征与指定的海报或图片进行合成,实现换脸的效果。该功能可以用于各种娱乐应用、社交媒体、相机应用和虚拟试妆等场景。1.功能介绍逼真和自然的换脸效果:相芯SDK使用先进的人脸识别和图像合成技术,确保换脸效果的逼真和......
  • SpringBoot+Flowable 完美结合,优雅实现工作流!
    1.2工作流是什么工作流,是把业务之间的各个步骤以及规则进行抽象和概括性的描述。使用特定的语言为业务流程建模,让其运行在计算机上,并让计算机进行计算和推动。工作流是复杂版本的状态机。2、BPMN2.0协议......
  • uniapp微信小程序微信同声传译和OCR支持功能
    1.首先小程序后台设置里面的第三方设置插件管理需要添加微信同声传译和OCR支持两个插件2.【微信同声传译】在manifest.json切换成源码视图然后在appid同级目录添加插件/*小程序特有相关*/"mp-weixin":{"appid":"wx9fd66d4d0e83c5f9","setting"......
  • TS4210D系列多功能激光调阻机
    ·设备可实现对集成电路各项参数的精密修调,如:电阻、电压、电流、周期、频率等;·自主研发的多通道测量系统(最多96通道),精度高、速度快、稳定可靠;·适用于各种厚膜电路;·可匹配不同规格的探针板连接器,兼容各型号标准探针板;另可定制飞针式测量结构.以满足特殊的修调需求;·采用高......
  • uniapp接入腾讯地图实现定位导航功能。
    转自:https://blog.csdn.net/qq_54753561/article/details/129500254 打开腾讯地图的官网注册账号登陆进入,滑入我的头像开发者信息:https://lbs.qq.com/service/webService/webServiceGuide/webServiceOverview 2找到添加的应用,添加key 3 webService API查询 4然后......
  • JavaWeb实现文件上传下载功能实例解析
    在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现。对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择......
  • PostgreSQL数据库开启 a=null等价于a is null 功能
    前言PostgreSQL官方文档:http://www.postgres.cn/docs/11/functions-comparison.html今天在预览PostgreSQL文档的时候看到了这个功能,平时写SQL都是ais[not]null来进行判断的,第一次见到可以这样,觉得挺新奇的就先记录下。ps:存在即合理。GOtransform_null_equals(boolean)是P......
  • 10道不得不会的SpringBoot面试题
    以下是SpringBoot面试题,相信大家都会有种及眼熟又陌生的感觉、看过可能在短暂的面试后又马上忘记了。JavaPub在这里整理这些容易忘记的重点知识及解答,建议收藏,经常温习查阅。来看看你会做几道1.为什么要用springboot?2.springboot有哪些优点?3.springboot核心配置文件是什......