【框架篇】统一用户登录权限验证

news2024/11/23 15:19:05

✅作者简介:大家好,我是小杨
📃个人主页:「小杨」的csdn博客

🐳希望大家多多支持🥰一起进步呀!


统一用户登录权限验证

1,自定义拦截器

对于统一用户登录权限验证的问题,Spring中提供了具体的解决方法,该方法为设置拦截器:HandlerInterceptor。

自定义拦截器的实现分为以下两个步骤:

  1. 创建自定义拦截器类,实现HandlerInterceptor接口,并重写preHandle方法,该方法在处理具体方法之前进行预处理。

  2. 将⾃定义拦截器配置到系统配置项,并且设置合理的拦截规则。实现 WebMvcConfigurer 的 addInterceptors ⽅法。


自定义拦截器创建

// 自定义拦截器创建
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession(false);
        if(session!=null && session.getAttribute("session_userinfo")!=null){
            return true;
        }
        response.setStatus(401);
        return false;
    }
}

自定义拦截器创建的实现代码解释:

1,创建自定义拦截器类,实现HandlerInterceptor接口,并重写preHandle方法,该方法在处理具体方法之前进行预处理。

2,preHandle方法的返回结果为t布尔类型的数据,当返回的数据为true时,表示拦截器验证成功,继续执行后续的操作流程,而当返回的结果为false时,表示拦截器验证失败,后续的操作流程就不再执行。


将⾃定义拦截器配置到系统配置项,并且设置合理的拦截规则

@Configuration
public class MyConfiguration implements WebMvcConfigurer {
    @Resource
    private LoginInterceptor loginInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(loginInterceptor)
                .addPathPatterns("/**") // 拦截所有的url
                .excludePathPatterns("/login"); // 排除名为login的url
    }
}

实现代码解释:

1,创建一个配置类(可使用@Configuration注解),实现WebMvcConfigurer接口,并重写addInterceptors方法。

2,registry为注册器,通过调用addInterceptor方法将自定义拦截器添加到系统配置项中。

3,将自定义拦截器添加到系统配置项中有两种写法,分别为:

  • 通过new方式添加:registry.addInterceptor(new LoginInterceptor())
  • 通过依赖注入方式添加:registry.addInterceptor(loginInterceptor)

4,addPathPatterns方法设置需要拦截的URL路径,可使用通配符进行匹配;excludePathPatterns方法设置需要排除的URL路径。

  • /**匹配所有的url路径,/*匹配一级的url路径

2,拦截器的实现原理

正常情况下业务的执行流程:用户或前端程序将请求发送到后端程序的控制器层Controller,经过控制器层Controller的参数校验操作之后,控制器层Controller根据业务代码的逻辑进行调用对应的服务层Service,然后服务层Service进行调用对应的数据持久层Mapper,数据持久层Mapper进而调用相对应的数据库,数据库将对应操作的数据依次返回给数据持久层Mapper,服务层Service,控制器层Controller,最后把数据返回给前端程序或者用户。

正常情况下业务的执行流程如下图所示:

而当添加了拦截器之后,会在调用 Controller 之前进行相应的业务处理,并根据业务处理结果决定后续的操作。

添加了拦截器之后,业务执行的流程如下图所示:


所有的 Controller 执⾏都会通过⼀个调度器 DispatcherServlet 来实现,这⼀点可以从 Spring Boot 控制台的打印信息看出,如下图所示:

而所有的方法都会执行 DispatcherServlet 中的 doDispatch 调度方法,doDispatch 源码如下:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HttpServletRequest processedRequest = request;
    HandlerExecutionChain mappedHandler = null;
    boolean multipartRequestParsed = false;
    ...
      // 检查是否为multipart/*类型
    processedRequest = checkMultipart(request);
    multipartRequestParsed = (processedRequest != request);

    
    if (mappedHandler == null) {
        noHandlerFound(processedRequest, response);
        return;
    }

    // 确认支持当前请求Handler的Adapter,用于调用Handler的handle方法
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

    // 处理last-modified请求头
    String method = request.getMethod();
    boolean isGet = "GET".equals(method);
    if (isGet || "HEAD".equals(method)) {
        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
        if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
            return;
        }
    }

    // 对拦截器链preHandle的调用
    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
        return;
    }

    // HandlerAdapter代理执行Handler的handle方法
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

    ...

    //进行视图的渲染
    applyDefaultViewName(processedRequest, mv);
    
    //调用拦截器链的postHandle方法
    mappedHandler.applyPostHandle(processedRequest, response, mv);
    ...
}

从上述源码可以看出在开始执行 Controller 之前,会先调用预处理方法 applyPreHandle。

image-20230906141918907

applyPreHandle 方法的具体实现源码如下:

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
    HandlerInterceptor[] interceptors = this.getInterceptors();
    if (!ObjectUtils.isEmpty(interceptors)) {
        for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {	
            //拦截器的preHandle方法返回true的时候顺带记录索引
            HandlerInterceptor interceptor = interceptors[i];
            if (!interceptor.preHandle(request, response, this.handler)) {	
                //一旦有个前置处理器没放行, 执行拦截器的afterCompletion方法
                this.triggerAfterCompletion(request, response, (Exception)null);
                return false;
            }
        }
    }
    return true;
}

从上述源码可以看出,在 applyPreHandle 中会获取所有的拦截器 HandlerInterceptor 并执行拦截器中的 preHandle 方法,这样就会咱们前⾯定义的拦截器对应上了。


结语

这就是本期博客的全部内容啦!如果有什么其他的问题无法自己解决,可以在评论区留言哦!

最后,如果你觉得这篇文章写的还不错的话或者有所收获的话,麻烦小伙伴们动动你们的小手,给个三连呗(点赞👍,评论✍,收藏📖),多多支持一下!各位的支持是我最大的动力,后期不断更新优质的内容来帮助大家,一起进步。那我们下期见!

在这里插入图片描述


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

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

相关文章

照片拼图软件 CollageIt Pro mac中文版功能特色

CollageIt Pro mac是一款拼图软件&#xff0c;CollageIt Pro for mac不仅支持多种模式的拼贴风格&#xff0c;还能够完美满足您对自己图片的美化需要&#xff0c;以一种全新的方式来呈现您收藏的图片&#xff0c;并且只需短短的几秒&#xff0c;便可以轻松实现将一组照片编程一…

黑色木工板覆膜板:耐用防水的建筑模板选择

黑色木工板覆膜板是一种耐用的建筑模板材料&#xff0c;以其优异的防水性能和稳定性成为建筑行业的理想选择。本文将重点介绍黑色木工板覆膜板的特点以及其在建筑模板领域的应用。 黑色木工板覆膜板采用杨木芯&#xff0c;并在表面覆盖一层黑色防水膜。杨木芯的选择使得木工板具…

多模块项目的搭建以及Nacos服务的发现与调用

这里写目录标题 多模块项目的搭建父项目的构建子模块的创建父子模块的意义 将注册服务引入到父子模块中创建子模块用于发现服务和调用供调用的服务接口创建调用子模块 测试一些小问题 在前文中我们实现了微服务的注册参考此文&#xff1a; Spring Cloud Alibaba中Nacos的安装&a…

3.表格-常用属性:th、align、valign布局方式

常用属性:th/align/valign 1、th 标签 定义表格内的表头单元格。 HTML 表单中有两种类型的单元格&#xff1a; 表头单元格 - 包含表头信息&#xff08;由 th 元素创建&#xff09; 标准单元格 - 包含数据&#xff08;由 td 元素创建&#xff09; th 定义表头内容&#xff0c;元…

年底赶项目?买核心板送开发板!T113核心板2款芯片6种配置选择

全志T113系列芯片是目前比较受欢迎的国产入门级嵌入式工业芯片。米尔是基于T113芯片开发较早、提供配置最全的厂家&#xff0c;是目前唯一一家提供T113-S和T113-i两种芯片核心板的厂家。更好的消息是&#xff0c;T113-i的核心板兼容T113-S的核心板&#xff0c;同一个硬件设计&a…

BUUCTF FLAG 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 注意&#xff1a;请将 hctf 替换为 flag 提交&#xff0c;格式 flag{} 密文&#xff1a; 下载附件&#xff0c;得到一张.png图片。 解题思路&#xff1a; 1、因为附件是一张图片&#xff0c;先放到StegSolve中&…

Dual Personalization on Federated Recommendation

联合推荐的双重个性化 代码链接 论文链接 主要创新 文章的主要创新是提出了一种双重个性化机制&#xff0c;用于增强联邦推荐系统的性能。这种机制能够在联邦学习框架中为每个本地模型学习用户特定的物品嵌入&#xff0c;从而显著提升推荐系统的效果。通过在四个数据集上进行…

搜维尔科技:网球运动员使用Xsens寻求精确的动作捕捉

就像其他一些运动一样,近年来网球迷们没有机会去参加许多真正优秀的模拟游戏,所以当一个人出现并承诺有这种体验时,很难不激动。开发者圆环游戏 匹配点:网球锦标赛 现在,我们承诺在单一支付者和多人组成部分的球场上有一个坚实的经验,我们对游戏和游戏的内部和外部都很好奇,我…

C#知识总结 基础篇(上)

本篇内容参考C#图解教程 本篇内容偏向基础&#xff0c;适合0基础的朋友快速上手&#xff0c;也适合有一定C语言&#xff08;或其他语言如C,java&#xff09;基础的人快速上手C#。同时适合unity引擎的初学者&#xff0c;更加详细的了解C#语言。 本文内容基本涵盖C#基础内容&am…

UG\NX二次开发 超长的对象属性值,怎么设置

文章作者:里海 来源网站:里海NX二次开发3000例专栏 感谢粉丝订阅 感谢 Dr. Lin 订阅本专栏,非常感谢。 简介 使用UF_ATTR_assign设置对象属性,如果属性值超过UF_ATTR_MAX_STRING_LEN则会报错。 #define UF_ATTR_MAX_STRING_LEN 132 怎么办呢?下面这种方法可以解决: 效果 …

从 Java 到 Rust,Substrate 优秀学员亲述 Web3 入门之路

你知道如何从 0 到 1 转行 Web3&#xff0c;找到技术开发岗位的一席之地吗&#xff1f;从后端核心开发到 Web3 测试&#xff0c;Substrate 课程优秀学员的区块链探索之路有哪些心得体会&#xff1f;10 月 26 日晚 20:00&#xff0c;第二期 Block Space 成长路径系列主题 AMA 活…

【el-cascader-panel】组件el-cascader-panel使用踩坑

需求背景&#xff1a;角色管理资源&#xff0c;资源返回树形结构数据&#xff0c;左侧树形展示列表可查询&#xff0c;右侧勾选资源权限平铺。 本身组件不支持全选&#xff0c;所以增加了全选按钮。覆写了级联面板宽度。可传只勾选code或者顺序当前节点二维数组列表。 效果 因…

Web测试是什么,有何特点?

Web测试是指对Web应用程序进行验证和评估的过程&#xff0c;以确保其功能、性能和安全性符合预期。 Web测试具体包括以下几个方面的内容&#xff1a; 功能测试&#xff1a;验证Web应用程序是否按照需求规格说明书中定义的功能正常工作。功能测试包括输入验证、表单提交、页面导…

【Jmeter】自动化测试实施

前言&#xff1a; Jmeter是目前最流行的一种测试工具&#xff0c;基于此工具我们搭建了一整套的自动化方案&#xff0c;包括了脚本添加配置、本地配置和运行、服务器配置等内容&#xff0c;完成了自动化测试闭环&#xff0c;通过这种快捷简便高效的方式&#xff0c;希望可以解…

【算法 | 哈希表 No.2】leetcode 219. 存在重复元素II

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

聊聊我对AI Agents技术的一些看法

小伙伴们&#xff01;我来兑现承诺啦&#xff5e; ps&#xff1a;接下来期待什么内容&#xff0c;欢迎在评论区留言&#xff01; 今天&#xff0c;我们就来聊聊大模型 Agent。 最近这几个月&#xff0c;Agent 这一概念可谓火出天际&#xff0c;从 AutoGPT 一周 6 万 star 刷新…

桥和割点,以及图的遍历树

目录 什么是桥 寻找桥的算法 代码实现 什么是割点 ​寻找割点的算法 代码实现 什么是桥 寻找桥的算法 代码实现 import java.util.ArrayList;public class FindBridges {private Graph G;private boolean[] visited;private int ord[];private int low[];private int cnt…

在钣金加工领域,迅镭激光切割机广泛使用的原因和优点何在?

激光切割工艺和激光切割设备正在被广泛的板材加工企业逐渐理解并接受&#xff0c;凭借其高效率的加工、高精度的加工、优质的切割断面、三维切割能力等诸多优势&#xff0c;逐步取代了传统的钣金切割设备。 苏州迅镭激光科技有限公司推出的激光切割设备的柔性化程度高&#xff…

Vue3 如何在<script setup>里设置组件name属性

Vue3 如何在<script setup>里设置组件name属性 文章目录 Vue3 如何在\<script setup>里设置组件name属性一、Vue组件中 name 的用处二、难看但实用的方法三、使用第三方插件支持安装插件插件基本配置插件基本使用 四、Vue官方解决方法4.1 Vue3.3版本之前安装插件插…