JWT学习笔记(二)权限校验

jwt格式实现权限校验

项目架构

在这里插入图片描述

项目依赖
   <!-- jwt工具包 -->
   <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.6.0</version>
    </dependency>
主要功能类
JwtUtils

创建解析token工具类

  • 创建token方法

        //签名私钥
        private String key = "laosan123456";
        //15分钟过期 1000*60*15 = 900000
        private Long ttl = 900000L;
    
    	public String createJwt(String id, String name, Map<String, Object> map) {
            //设置失效时间
            long now = System.currentTimeMillis();//当前毫秒
            long exp = now + ttl;
            //创建jwtBuilder
            JwtBuilder jwtBuilder = Jwts.builder().setId(id).setSubject(name)
                    .setIssuedAt(new Date())
                    .signWith(SignatureAlgorithm.HS256, key);
            //根据map设置claims,即用户自定义数据
            for (Map.Entry<String, Object> entry : map.entrySet()) {
                jwtBuilder.claim(entry.getKey(), entry.getValue());
            }
            jwtBuilder.setExpiration(new Date(exp));
            //创建token
            String token = jwtBuilder.compact();
            return token;
        }
    
  • 解析token 方法

        public Claims parseJwt(String token) {
    		return Jwts.parser().setSigningKey(key).parseClaimsJws(token).getBody();
        }
    
UserController

用户登录接口即token相关功能验证

  • 用户登录

        /**
         * 用户登录
         */
        @PostMapping(value = "/login")
        public String login(@RequestBody Map<String, String> loginMap) {
            String username = loginMap.get("username");
            String password = loginMap.get("password");
            //TODO 数据库校验,成功则返回,此处没有走数据库在,直接判断用户名和密码是否相同
            if (!username.equals(password)) {
                return "用户名密码错误";
            }
            //登录成功设置基本信息
            Map<String, Object> map = new HashMap<>();
            // 设置用户基本信息
            map.put("userId", "123456123465");
            map.put("username", "laosan");
            // 设置用户可以访问的api权限信息;
            map.put("apis", "user.detail");
            return jwtUtils.createJwt("123", username, map);
        }
    
  • 用户详情接口

        /**
         * 获取用户基本信息,用于控制前台菜单,按钮的显示
         */
        @PostMapping(value = "/detail", name = "user.detail")
        public Object detail(HttpServletRequest request) {
            //claims从base中获取
            String userid = claims.getId();
            //TODO 根据userId从数据库中获取用户的角色、权限、菜单、按钮等信息
            Map<String, String> result = new HashMap<>();
            // TODO 以下数据从数据库中获取,
            result.put("menus", "app-menu");//菜单
            result.put("button", "app-delete"); //按钮
            return result;
        }
    
JwtInterceptor

jwt拦截器代码继承HandlerInterceptorAdapter类,并重写preHandle方法,用于校验当前用户是否有访问该接口的权限,此处根据PostMapping中name属性做权限判断;

  • 具体拦截器代码

        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 通过request获取请求token信息
            String token = request.getHeader("token");
            //判断请求头信息是否为空
            if (!StringUtils.isEmpty(token)) {
                //解析token获取claims
                Claims claims = null;
                try {
                    claims = jwtUtils.parseJwt(token);
                } catch (Exception e) {
                    throw new Exception("token exception");
                }
                if (claims != null) {
                    //通过claims获取到当前用户的可访问API权限字符串
                    String apis = (String) claims.get("apis");
                    HandlerMethod handlerMethod = (HandlerMethod) handler;
                    //获取当前请求接口中的name属性
                    String name = handlerMethod.getMethodAnnotation(RequestMapping.class).name();
                    //判断当前用户是否具有响应的请求权限
                    if (apis.contains(name)) {
                        request.setAttribute("claims", claims);
                        return true;
                    } else {
                        throw new Exception("no permission");
                    }
                }
            }
            throw new Exception("no token");
        }
    
UserConfig

拦截器配置类,继承WebMvcConfigurationSupport,并重写方法addInterceptors;

    @Override
    protected void addInterceptors(InterceptorRegistry registry) {
        //添加自定义拦截器
        registry.addInterceptor(jwtInterceptor).
                addPathPatterns("/**").//指定拦截器的url地址
                excludePathPatterns("/user/login");// 指定不拦截的url地址
    }
GlobalExceptionHandler

全局捕获异常类,主要助理拦截器代码抛出的异常,以固定格式返回给前台,此处可定义多种异常;

    @ExceptionHandler(value = Exception.class)
    @ResponseBody
    public String error(HttpServletRequest request, HttpServletResponse response, Exception e) {
        e.printStackTrace();
        return e.getMessage();
    }
简单测试
获取token
  • 获取token
    在这里插入图片描述
token异常
  • 无token
    在这里插入图片描述

  • token无效
    在这里插入图片描述

权限校验
  • 无权限:login接口中apis没有该接口对应的权限;
    在这里插入图片描述

  • 有权限:login接口中apis有该接口对应的权限;
    在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值