【shiro】13.验证码过滤器

news/2024/10/25 9:27:51/文章来源:https://www.cnblogs.com/luyj00436/p/18474582

通过之前的学习,我们知道如果自定义过滤器的使用。接下来,查看ruoyi源码,我们需要在过滤器中实现验证码。

前提

  • 已新建SpringBoot项目
  • 项目以成功集成shiro,并完成简单配置
  • 已完成路由配置,包含登录页面/login和首页index
  • 已经知道如何使用和自定义过滤器

思路

1. Shiro的配置页面,添加自定义过滤器。过滤器需要传递两个参数:  captchaEnabled (验证码开关)和  captchaType  (验证码类型)。

2. 新建自定义过滤器,继承抽象类 AccessControlFilter 。在这里实现方法 isAccessAllowed (过滤前操作)(重点)和 onAccessDenied 验证失败后处理方法。我们把页面获取到的验证码和Session中得到的验证码进行对比。每次对比成功后,都要清除Session。

3. 新建绘制验证码并保存Session的接口。

4. 前端页面,添加验证码提交和验证码图片,用于提交时对比和绘制验证码。

步骤

1. 添加自定义过滤器。在配置文件(application.yml)添加两个参数 captchaEnabled (验证码开关)和 captchaType (验证码类型)。

1 # shiro配置
2 shiro:
3   user:
4     loginUrl: /login
5     captchaEnabled : true
6     captchaType: math

 

ShiroConfiguration.java 添加配置器的引用。

 1 /**
 2  * 验证码开关
 3  */
 4 @Value("${shiro.user.captchaEnabled}")
 5 private boolean captchaEnabled;
 6 
 7 /**
 8  * 验证码类型
 9  */
10 @Value("${shiro.user.captchaType}")
11 private String captchaType;

 

在拦截器添加登录页面的验证码接口

 过滤器方法如下:

 1 /**
 2  * 自定义验证码
 3  * @return
 4  */
 5 private Filter myCaptcha() {
 6     MyCaptchaFilter myCaptchaFilter = new MyCaptchaFilter();
 7     myCaptchaFilter.setCaptchaEnabled(captchaEnabled);
 8     myCaptchaFilter.setCaptchaType(captchaType);
 9     return myCaptchaFilter;
10 }

2. 自定义验证码过滤器,继承抽象类 AccessControlFilter 。添加接收参数的方法。

 1 /**
 2  * 验证码开关
 3  */
 4 private boolean captchaEnabled = true;
 5 
 6 /**
 7  * 验证码类型
 8  */
 9 private String captchaType= "math";
10 
11 public void setCaptchaEnabled(boolean captchaEnabled) {
12     this.captchaEnabled = captchaEnabled;
13 }
14 
15 public void setCaptchaType(String captchaType) {
16     this.captchaType = captchaType;
17 }

继承过滤前验证方法。当获取到的接口类型为“post”时且开启验证码时,进行验证,否则不进行验证。(验证方法,对比post请求的code和Session是否一致),返回true则放行下一个拦截器,返回false则执行 onAccessDenied 代码。

 1  @Override
 2 protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) throws Exception {
 3     HttpServletRequest httpServletRequest = (HttpServletRequest) request;
 4     if(!captchaEnabled || !"post".equals(httpServletRequest.getMethod().toLowerCase())){
 5         return true;
 6     }
 7     return validateResponse(httpServletRequest, httpServletRequest.getParameter(ShiroConstants.CURRENT_VALIDATECODE));  //  public static final String CURRENT_VALIDATECODE = "validateCode";
 8 }
 9 
10 private boolean validateResponse(HttpServletRequest request, String validateCode) {
11     Object obj = ShiroUtils.getSession().getAttribute("KAPTCHA_SESSION_KEY");
12     String code = String.valueOf(obj != null ? obj : "");
13     System.out.println("code:"+code);
14     System.out.println("validateCode:"+validateCode);
15     // 验证码清除,防止多次使用。
16     request.getSession().removeAttribute("KAPTCHA_SESSION_KEY");
17     if (StringUtils.isEmpty(validateCode) || !validateCode.equalsIgnoreCase(code))
18     {
19         return false;
20     }
21     return  true;
22 }

 验证后的处理方法。返回true则放行下一个拦截器,返回false,则不放行下一个拦截器。

1 @Override
2 protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception {
3     request.setAttribute(ShiroConstants.CURRENT_CAPTCHA, ShiroConstants.CAPTCHA_ERROR);//  request.setAttribute("captcha", "captchaError");
4     return false;
5 }

 3.新建绘制验证码并保存Session的接口。实际使用中,验证码的绘制可能更复杂,单独引用在其他地方。这里,简单引用随机生成N位数字的方式。使用BufferImage设置背景和每个字符。

 1 **
 2  * 图片验证码
 3  * 
 4  * @author ruoyi
 5  */
 6 @Controller
 7 @RequestMapping("/captcha")
 8 public class SysCaptchaController extends BaseController
 9 {
10     /**
11      * 页面验证码图片生成(并将图片存入session)
12      */
13     @GetMapping(value = "/captchaImage")
14     public ModelAndView getKaptchaImage(HttpServletRequest request, HttpServletResponse response) throws IOException {
15         int width = 120;
16         int height = 40;
17         BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
18         // 生成验证码
19         String code = generateCode(4);
20         // 绘制验证码
21         drawCaptcha(bufferedImage, code);
22         // 将验证码存入session
23         request.getSession().setAttribute("KAPTCHA_SESSION_KEY", code);
24         // 设置响应头
25         response.setContentType("image/jpeg");
26         response.setHeader("Pragma", "No-cache");
27         response.setHeader("Cache-Control", "no-cache");
28         response.setDateHeader("Expires", 0);
29         // 输出图片
30         ImageIO.write(bufferedImage,"jpg",response.getOutputStream());
31 
32         return  null;
33     }
34 
35     /**
36      * 生成验证码
37      * @param length
38      * @return
39      */
40     private String generateCode(int length){
41         Random random = new Random();
42         StringBuffer sb = new StringBuffer();
43         for (int i = 0; i < length; i++) {
44             sb.append(random.nextInt(10));
45         }
46         return sb.toString();
47     }
48 
49     /**
50      * 绘制验证码(可以自定义验证码的样式和细节)
51      * @param bufferedImage
52      * @param code
53      */
54     private void drawCaptcha(BufferedImage bufferedImage, String code) {
55         Graphics graphics = bufferedImage.getGraphics();
56         Random random = new Random();
57         // 设置背景
58         graphics.setColor(Color.WHITE);
59         graphics.fillRect(0, 0, bufferedImage.getWidth(), bufferedImage.getHeight());
60         // 随机设置每个字符的颜色
61         for (int i = 0; i < code.length(); i++) {
62             Font font = new Font("Times New Roman", Font.BOLD, 30);
63             graphics.setColor(getColor(random));
64             graphics.setFont(font);
65             graphics.drawString(String.valueOf(code.charAt(i)), 30*i + 10, 30);
66         }
67 
68         graphics.dispose();
69     }
70 
71     // 字符随机颜色
72     private static Color getColor(Random random) {
73         return new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
74     }
75 
76 }

4. 前端页面,添加验证码提交和验证码图片,用于提交时对比和绘制验证码。 Math.random() 用于生成随机数。src路径变化,则会调用后台接口,改变验证码。

1 <div  th:if="${captchaEnabled==true}">
2     <div >
3         验证码:<input type="text" name="validateCode" placeholder="验证码" maxlength="5" />
4     </div>
5     <div >
6         <img th:src="/captcha/captchaImage"  title="点击刷新验证码" width="120" height="40" onclick="this.src='/captcha/captchaImage?'+Math.random()" />
7     </div>
8 </div>

 

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

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

相关文章

macOS 13 Ventura (苹果最新系统)v13.7正式版

Apple 今日发布了 macOS 的下一个版本,称为macOS Ventura,它具有多项新功能,包括 Stage Manager、Continuity Camera、新的安全更新等。完整的兼容性列表如下:iMac(2017 年及更高版本) iMac Pro MacBook air(2018 年及更新机型) MacBook Pro(2017 年及更新机型) Mac …

蓝桥杯大赛 ——首场算法团队战题解

1. 不同角度【算法赛】 在生活中,我们总是根据数值的大小来判断两个数字的大小关系。例如,9999 总是小于 100100,999999 总是小于 10001000。但如果我们换一个角度,将 999999 和 10001000 看成是两个数字字符串,并用字典序来比较它们的大小,那么此时,999999 将大于 1000…

挖宝国内良心核心期刊,免审稿费,免版面费,还有奖励,更有温度

❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀ https://blog.csdn.net/u011344545/article/details/143167586 github:https://github.com/MichaelBeechanCSDN:https://blog.csdn.net/u011344545 ❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀❀ 话说科研…

HarmonyOS:基于Web组件构建网络应用(1)

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤博客园地址:为敢技术(https://www.cnblogs.com/strengthen/ )➤GitHub地址:https://github.com/strengthen➤原文地址:https://www.cnblogs.com/strengthen/p/18499435➤如果链接不是为敢技术的博…

关于决策树的理解

近期在项目中使用了规则树这一设计模式,感觉和决策链来说是有些区别的 1.决策链是链型的,走的是链,流程都要完整的走一遍 2.决策链用的一种嵌套,基于函数结尾重新调用next的函数直至结束 但是规则树不一样 规则树是基于类似二叉树的结构,有的通过有的不通过 ,并且它每层都用Lis…

半导体晶圆厂如何保持 可靠安全又高效的跨网文件交换?

晶圆厂是半导体产业链最重要的一环,它位于半导体制造的中游,在这个过程中,IC设计公司将芯片设计正式进行投产,晶圆厂制造晶圆后,再应用于下游的汽车、手机、通信等不同行业。 半导体晶圆厂为了数据安全,通常会进行网络隔离,对于大型晶圆厂,网络隔离会非常细致,如晶圆…

Abp-VNext用户权限管理系列文章---工作流

一、工作流的使用 1、工作流定义图,我们定义了一个订单的工作审批流2、创建的可以审批的用户,密码都为Bridge0 发起流程:用户wf_order_creator 订单创建员 采购科员审核:角色: 采购科员 用户:wf_order_officer +订单审核科员 采购科长审核: wf_order_deptHead 订…

进入网站后台修改不了?模板网站能修改代码吗?

大多数模板网站允许用户在一定范围内自定义和修改代码,尤其是对于HTML、CSS和JavaScript等前端代码。 限制与权限:一些模板网站可能对代码编辑有特定的限制,例如仅允许修改样式或内容,而不允许更改结构或添加复杂的脚本。 高级功能:部分高级模板服务提供更灵活的代码编辑选…

网站模板修改上传图片?模板如何修改网站logo?

确定图片上传的位置确定在网站的哪个部分需要添加图片上传功能,例如用户资料页面、产品详情页等。HTML 表单设置在需要上传图片的地方添加一个表单,使用 <form> 标签,并确保 enctype 属性设置为 multipart/form-data,这允许文件数据被正确编码。<form action=&quo…

10月25日 交易计划

1. 玻璃 玻璃周波反弹最终目标1390附近 今日在1334-1324间 可以加多 看1390

VMware vSphere 8.0 Update 3d 下载 - 企业级工作负载平台

VMware vSphere 8.0 Update 3d 下载 - 企业级工作负载平台VMware vSphere 8.0 Update 3d 下载 - 企业级工作负载平台 vSphere 8.0U3 | ESXi 8.0U3 & vCenter Server 8.0U3 请访问原文链接:https://sysin.org/blog/vmware-vsphere-8-u3/ 查看最新版。原创作品,转载请保留出…

10.21 ~ 10.27

CSP10.21 Day -4 快 CSP 啦…… 话说真的应该这么早就开始记“Day x”吗 为啥这几天这么冷啊要冻死了 😥 上午模拟赛。 开题。看 T1,发现自己又不会 T1。 不行今天一定要签上! 然后磕了一个小时 T1,还是不会。 算了一下发现暴力是 \(O(n!)\),\(n\) 最大可达 \(15\),直接…