• 简单的权限验证


    登录与授权

    前言:如果采用spring家族进行后端开发,想要实现多用户多权限很容易联想到spring security,shiro两大常见框架,但是两者都有一定的学习成本,并且由于兼容了很多设计模式的思想,源码很复杂,短时间不容易上手。那么,我们能不能通过一些java基础知识实现呢?因此本文使用注解+拦截器实现多用户多权限功能。

    多用户是什么?比如,课堂中有授课的老师,听课的学生,这就是两种类型的用户。

    多权限是什么?老师拥有授课权限,学生具有听课权限。非学生无听课权限,非老师无授课权限,如学生无授课权限。

    在这里插入图片描述

    构建一个基本的多用户多权限应用场景,学生和教师可进入学校,教师可授课,学生可听课。在生活中是怎么实现的呢?门卫大叔查看你的学生或教师信息确认为本校人员,学生通过课程表进入可进入的教室听课,非课程表内的教室为其他用户占用,教师同理。

    在这里插入图片描述

    观察得,多用户多权限系统需要一个门卫查岗的系统,进入系统后用户根据用户身份拥有不同权限。那么我们怎么用java程序实现呢?我们可选择使用拦截器拦截除登录外的所有访问系统的路劲,实现“查岗”即登录操作。用户登录后我们返回前端一个标识用户的信息字段“token”字段,用户访问非登录路径时携带token字段,通过拦截器我们可以解析token获取用户拥有的权限,在访问具体的路径方法时,我们可以通过注解配置访问该路径方法需要的权限。如此便实现多用户多权限登录。

    以下是结合代码进行实战:

    我们先整理好一个开发的思路,首先是使用springboot进行开发,使用jwt加密传递的token字段,使用redis缓存不同的token键对应的用户信息值。使用拦截器拦截非登录方法,拦截时获取用户的权限,访问方法时通过注解获取方法需要的用户权限进行校验。

    实现作用:使用用户类型标识用户权限,一个路径方法可配置多用户访问,用户可有多角色,用户拥有其中一种角色即可。适用于粗粒度系统。

    注解

    • 登录注解

      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.TYPE, ElementType.METHOD})
      public @interface LoginRequired {
      }
      
      • 1
      • 2
      • 3
      • 4
    • 鉴权注解

      @LoginRequired//使用了登录注解,先登录再鉴权
      @Retention(RetentionPolicy.RUNTIME)
      @Target({ElementType.TYPE, ElementType.METHOD})
      public @interface PermissionRequired {
          /**
           * 角色,默认游客权限
           *
           * @return
           */
          UserType[] userType() default {UserType.VISITOR};
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

    token

    使用token时,可以使用jwt进行加密传输,同时可以在服务度对jwt进行加盐

    //存入
    String token = JwtUtil.createJWT("标识字段");    
    redisCache.setCacheObject("盐"+"标识字段",user);
    return token;
    //取出
     标识字段 = JwtUtil.parseJWT(token).getSubject();
     User user = redisCache.getCacheObject("盐"+"标识字段");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    易错点

    注入拦截器到spring容器中,不注意的话,很容易犯下关于redistemplete的空指针异常。原因是拦截器是最先执行的,此时未初始化bean,因此在拦截类使用的redistemplete此时为空。

    如,此时在拦截器内不能使用任何bean

    @Configuration
    public class MvcConfig implements WebMvcConfigurer {
        
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(new LoginInterceptor())
                    .addPathPatterns("/**");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    推荐写法为

    @Configuration
    public class MvcConfig implements WebMvcConfigurer {
    
        @Bean
        public LoginInterceptor getLoginInterceptor(){
            return new LoginInterceptor();
        }
    
        @Override
        public void addInterceptors(InterceptorRegistry registry) {
            registry.addInterceptor(getLoginInterceptor())
                    .addPathPatterns("/**")
            .excludePathPatterns("/login");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    还有一些比较基础的代码不在此阐述,比如在拦截器中查询用户的用户角色并缓存在redis中,并且校验。

    下面的云盘包含所有代码以及sql,仅供参考。项目中采用的微信登录,读者可更改使用即可,不影响系统功能的完整性。

    链接:https://pan.baidu.com/s/1mfBJioyA5C7pVAIYE3fLSw?pwd=wang
    提取码:wang

    本文参考了众多博客的思路,如侵权,请您联系。

  • 相关阅读:
    Apifox --- 全套服务提升了团队效率,让研测之间充满了爱(记Apifox在工程中的实际应用)【云原生】
    JavaScript-DOM按钮事件
    Springboot常用的请求方式注解(@RequestMapping、@PutMapping、@DeleteMapping、@PostMapping)
    No165.精选前端面试题,享受每天的挑战和学习
    mybatis拦截器实现数据权限
    Python 基础面试第四弹
    网络通信 | 内网穿透
    WebGL层次模型——单节点模型
    迁移学习
    五年数据库专家,带你深入高性能 MySQL 架构系统,不要等到面试再追悔莫及
  • 原文地址:https://blog.csdn.net/weixin_51454454/article/details/127642550