springboot切面实现token权限校验

目录

数据表

使用token

实体类

权限枚举类

自定义注解

控制层添加注解

添加控制层切面

RedisUtil工具类

测试

登陆

执行权限所需20以上的查询用户操作

执行权限所需100以上的删除用户操作


我展示我项目中实现的效果,仅提供思路,请按需使用代码

数据表

要实现权限校验,首先数据表和实体类上需要有权限字段,我的表中permission和gender是通过外键约束permission表和gender表实现枚举的,因为可拓展性更好

/*
 Navicat Premium Data Transfer

 Source Server         : Yan
 Source Server Type    : MySQL
 Source Server Version : 80027
 Source Host           : localhost:3306
 Source Schema         : coc

 Target Server Type    : MySQL
 Target Server Version : 80027
 File Encoding         : 65001

 Date: 07/05/2023 20:00:45
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` varchar(25) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '主键',
  `account` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '账号',
  `password` varchar(60) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '密码',
  `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '姓名',
  `gender` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT '未知' COMMENT '性别',
  `telephone` varchar(15) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '手机号',
  `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT NULL COMMENT '邮箱',
  `signature` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '无签名' COMMENT '签名',
  `avatar_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT 'C:\\Users\\Yan\\Desktop\\user\\avatar\\avatar.jpg' COMMENT '头像地址',
  `permission` int NULL DEFAULT 20 COMMENT '权限',
  `banned` bit(1) NULL DEFAULT b'0' COMMENT '是否被封禁',
  `remark` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NULL DEFAULT '无备注' COMMENT '备注',
  `create_time` datetime NOT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`) USING BTREE,
  INDEX `f_gender`(`gender` ASC) USING BTREE,
  INDEX `f_permission`(`permission` ASC) USING BTREE,
  CONSTRAINT `f_gender` FOREIGN KEY (`gender`) REFERENCES `gender` (`gender_name`) ON DELETE RESTRICT ON UPDATE CASCADE,
  CONSTRAINT `f_permission` FOREIGN KEY (`permission`) REFERENCES `permission` (`weight`) ON DELETE RESTRICT ON UPDATE CASCADE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci ROW_FORMAT = DYNAMIC;

SET FOREIGN_KEY_CHECKS = 1;

 springboot切面实现token权限校验_第1张图片

 springboot切面实现token权限校验_第2张图片

使用token

项目使用token校验,那么可以通过请求发送过来的token取到redis缓存中token对应的用户id,因此需要一个存放token:id的hash表,由于我做的token验证直接从表中取token校验,同时也需要取对应的id,所以token和id互为key和value

springboot切面实现token权限校验_第3张图片

实体类

这是我用mybatis-plsu-generator根据数据表自动生成的

package com.greenjiao.coc.bean;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import java.time.LocalDateTime;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
import lombok.Data;

/**
 * 

* *

* * @author yan * @since 2023-05-07 */ @Data @TableName("user") public class User { /** * 主键 */ @TableId(value = "id", type = IdType.ASSIGN_ID) private String id; /** * 账号 */ @TableField("account") private String account; /** * 密码 */ @TableField("password") private String password; /** * 姓名 */ @TableField("name") private String name; /** * 性别 */ @TableField("gender") private String gender; /** * 手机号 */ @TableField("telephone") private String telephone; /** * 邮箱 */ @TableField("email") private String email; /** * 签名 */ @TableField("signature") private String signature; /** * 头像地址 */ @TableField("avatar_address") private String avatarAddress; /** * 权限 */ @TableField("permission") private Integer permission; /** * 是否被封禁 */ @TableField("banned") private Boolean banned; /** * 备注 */ @TableField("remark") private String remark; /** * 创建时间 */ @TableField("create_time") @JsonDeserialize(using = LocalDateTimeDeserializer.class) @JsonSerialize(using = LocalDateTimeSerializer.class) @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") private LocalDateTime createTime; }

权限枚举类

定义不同权限身份

package com.greenjiao.coc.common.enumconstant;

/**
 * 权限信息
 */
public enum PERMISSION_TYPE {
    BANNED_USER(0, "封禁用户"),
    BLOCKED_SPEECH_USER(10, "禁言用户"),
    NORMAL_USER(20, "普通用户"),
    PREMIUM_USER(30, "高级用户"),
    NORMAL_ADMIN(100, "管理员"),
    TOP_ADMIN(999, "最高管理员");
    private final Integer weight;
    private final String name;

    PERMISSION_TYPE(Integer weight, String name) {
        this.weight = weight;
        this.name = name;
    }

    public Integer getWeight() {
        return weight;
    }

    public String getName() {
        return name;
    }
}

自定义注解

我们需要对一些控制层中特定的方法进行权限校验,并且部分方法的权限要求可能是不同的,所以需要给方法添加自定义注解,注解中包含所需的权限

package com.greenjiao.coc.annotation;

import com.greenjiao.coc.common.enumconstant.PERMISSION_TYPE;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
 * 权限校验注解
 */
@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Role {
    PERMISSION_TYPE permission() default PERMISSION_TYPE.TOP_ADMIN;
}

控制层添加注解

我的用户的控制层,除了登陆和注册外,其他的方法都使用自定义注解Role设置对应所需权限

package com.greenjiao.coc.controller;

import com.greenjiao.coc.annotation.Role;
import com.greenjiao.coc.bean.User;
import com.greenjiao.coc.common.DataVO;
import com.greenjiao.coc.common.enumconstant.PERMISSION_TYPE;
import com.greenjiao.coc.service.impl.UserServiceImpl;
import org.springframework.web.bind.annotation.*;

import java.util.Map;

@RestController
@RequestMapping("/coc/user")
public class UserController {
    private final UserServiceImpl userService;

    public UserController(UserServiceImpl userService) {
        this.userService = userService;
    }

    @PostMapping("/register")
    public DataVO register(@RequestBody User user) {
        return userService.register(user);
    }

    @PostMapping("/login")
    public DataVO> login(@RequestBody User user) {
        return userService.login(user);
    }

    @Role(permission = PERMISSION_TYPE.NORMAL_USER)
    @PutMapping
    public DataVO update(@RequestBody User user) {
        return userService.update(user);
    }

    @Role(permission = PERMISSION_TYPE.NORMAL_ADMIN)
    @DeleteMapping("/{id}")
    public DataVO delete(@PathVariable String id) {
        return userService.delete(id);
    }

    @Role(permission = PERMISSION_TYPE.NORMAL_USER)
    @GetMapping
    public DataVO selectAll(@RequestBody User user) {
        return userService.selectAll(user);
    }
}

添加控制层切面

添加其中的权限校验@Before注解指定切点

需要权限校验的切点为controller包下所有类的所有方法,并且要拥有Role注解

package com.greenjiao.coc.aspect;


import com.alibaba.fastjson2.JSON;
import com.greenjiao.coc.annotation.Role;
import com.greenjiao.coc.bean.User;
import com.greenjiao.coc.common.DataVO;
import com.greenjiao.coc.common.ServerConstants;
import com.greenjiao.coc.exception.ExceptionEnum;
import com.greenjiao.coc.exception.ExceptionTip;
import com.greenjiao.coc.mapper.UserMapper;
import com.greenjiao.coc.util.MyUtil;
import com.greenjiao.coc.util.RedisUtil;
import jakarta.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Aspect
@Component
public class ControllerAspect {
    private final RedisUtil redisUtil;
    private final UserMapper userMapper;

    public ControllerAspect(RedisUtil redisUtil, UserMapper userMapper) {
        this.redisUtil = redisUtil;
        this.userMapper = userMapper;
    }

    // 指定切点为controller目录中所有类的selectAll方法并且要求携带的参数是Map param
    @Pointcut(value = "execution(* com.greenjiao.coc.controller..selectAll(..)) && args(param)", argNames = "param")
    public void controllerPoint(Map param) {
    }

    @Pointcut(value = "execution(* com.greenjiao.coc.controller..*(..)) && @annotation(com.greenjiao.coc.annotation.Role)")
    public void controllerCheckRolePoint() {
    }

    /**
     * 将查询的内容统一转为对应实体类
     * @param joinPoint
     * @param param
     * @return
     * @throws Throwable
     */
    @Around(value = "controllerPoint(param) && args(..)", argNames = "joinPoint,param")
    public Object changeParam(ProceedingJoinPoint joinPoint, @RequestBody Map param) throws Throwable {
        Integer page = (Integer) param.get(ServerConstants.DEFAULT_PAGE_NAME);  //获得param中用于分页的page和limit后将其移除,剩余在param中的键值对即为需要查询的条件
        param.remove(ServerConstants.DEFAULT_PAGE_NAME);
        Integer limit = (Integer) param.get(ServerConstants.DEFAULT_LIMIT_NAME);
        param.remove(ServerConstants.DEFAULT_LIMIT_NAME);

        String className = MyUtil.getClassName(joinPoint.getTarget().getClass().getName());    //工具类获取全限定类名
        Class clazz = Class.forName(className);  //反射机制创建类
        Object obj = JSON.parseObject(JSON.toJSONString(param), clazz); //将Map中剩余的键值对转为对应类型的json对象

        Map params = new HashMap<>();          //重新存放最后需要新返回的参数,procceed方法的参数需要一个Object数组,
        params.put(ServerConstants.DEFAULT_BEAN_NAME, obj);      //但是controller层中的selectAll方法又只有一个参数,
        params.put(ServerConstants.DEFAULT_PAGE_NAME, page);     //如果直接将键值对放到Object数组中将会报参数个数异常,
        params.put(ServerConstants.DEFAULT_LIMIT_NAME, limit);   //所以这里将键值对放到Map中,再将Map放到Object数组中

        return joinPoint.proceed(new Object[]{params}); //procceed方法的参数需要一个Object数组,
    }

    /**
     * 权限校验
     */
    @Before("controllerCheckRolePoint()")
    public void checkRole(JoinPoint joinPoint){
        // 获取Role注解中的permission权重值
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        Role role = method.getAnnotation(Role.class);
        Integer requiredWeight = role.permission().getWeight();

        // 从redis表中查找token对应的id,获取对应的用户
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String token = request.getHeader("token");
        String id = (String) redisUtil.hget(ServerConstants.REDIS_TOKEN_TABLE_NAME, token);
        User user = userMapper.selectById(id);

        // 校验
        if(user.getPermission() < requiredWeight){
            throw new ExceptionTip(ExceptionEnum.LOW_PERMISSION);
        }
    }
}

RedisUtil工具类

这是我权限校验使用的RedisUtil工具类,由于无用的警告太多,看的烦我用@SuppressWarnings注解将所有警告忽略了

并且将其给Spring管理了,所以可以在其他地方自动注入

package com.greenjiao.coc.util;

import jakarta.annotation.Resource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * Redis工具类
 */
@SuppressWarnings("all")
@Component
public class RedisUtil {
    @Resource
    private RedisTemplate redisTemplate;

    /****************** common start ****************/
    /**
     * 指定缓存失效时间
     *
     * @param key  键
     * @param time 时间(秒)
     * @return
     */
    public boolean expire(String key, long time) {
        try {
            if (time > 0) {
                redisTemplate.expire(key, time, TimeUnit.SECONDS);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据key 获取过期时间
     *
     * @param key 键 不能为null
     * @return 时间(秒) 返回0代表为永久有效
     */
    public long getExpire(String key) {
        return redisTemplate.getExpire(key, TimeUnit.SECONDS);
    }

    /**
     * 判断key是否存在
     *
     * @param key 键
     * @return true 存在 false不存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除缓存
     *
     * @param key 可以传一个值 或多个
     */
    @SuppressWarnings("unchecked")
    public void del(String... key) {
        if (key != null && key.length > 0) {
            if (key.length == 1) {
                redisTemplate.delete(key[0]);
            } else {
                redisTemplate.delete((Collection) CollectionUtils.arrayToList(key));
            }
        }
    }
    /****************** common end ****************/


    /****************** String start ****************/

    /**
     * 普通缓存获取
     *
     * @param key 键
     * @return 值
     */
    public Object get(String key) {
        return key == null ? null : redisTemplate.opsForValue().get(key);
    }

    /**
     * 普通缓存放入
     *
     * @param key   键
     * @param value 值
     * @return true成功 false失败
     */
    public boolean set(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 普通缓存放入并设置时间
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期
     * @return true成功 false 失败
     */
    public boolean set(String key, Object value, long time) {
        try {
            if (time > 0) {
                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
            } else {
                set(key, value);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 递增
     *
     * @param key   键
     * @param delta 要增加几(大于0)
     * @return
     */
    public long incr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递增因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }

    /**
     * 递减
     *
     * @param key   键
     * @param delta 要减少几(小于0)
     * @return
     */
    public long decr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }
    /****************** String end ****************/


    /****************** Map start ****************/

    /**
     * HashGet
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return 值
     */
    public Object hget(String key, String item) {
        return redisTemplate.opsForHash().get(key, item);
    }

    /**
     * 获取hashKey对应的所有键值
     *
     * @param key 键
     * @return 对应的多个键值
     */
    public Map hmget(String key) {
        return redisTemplate.opsForHash().entries(key);
    }

    /**
     * HashSet
     *
     * @param key 键
     * @param map 对应多个键值
     * @return true 成功 false 失败
     */
    public boolean hmset(String key, Map map) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * HashSet 并设置时间
     *
     * @param key  键
     * @param map  对应多个键值
     * @param time 时间(秒)
     * @return true成功 false失败
     */
    public boolean hmset(String key, Map map, long time) {
        try {
            redisTemplate.opsForHash().putAll(key, map);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 向一张hash表中放入数据,如果不存在将创建
     *
     * @param key   键
     * @param item  项
     * @param value 值
     * @param time  时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
     * @return true 成功 false失败
     */
    public boolean hset(String key, String item, Object value, long time) {
        try {
            redisTemplate.opsForHash().put(key, item, value);
            if (time > 0) {
                expire(key, time);
            }
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 删除hash表中的值
     *
     * @param key  键 不能为null
     * @param item 项 可以使多个 不能为null
     */
    public void hdel(String key, Object... item) {
        redisTemplate.opsForHash().delete(key, item);
    }

    /**
     * 判断hash表中是否有该项的值
     *
     * @param key  键 不能为null
     * @param item 项 不能为null
     * @return true 存在 false不存在
     */
    public boolean hHasKey(String key, String item) {
        return redisTemplate.opsForHash().hasKey(key, item);
    }

    /**
     * hash递增 如果不存在,就会创建一个 并把新增后的值返回
     *
     * @param key  键
     * @param item 项
     * @param by   要增加几(大于0)
     * @return
     */
    public double hincr(String key, String item, long by) {
        return redisTemplate.opsForHash().increment(key, item, by);
    }

    /**
     * hash递减
     *
     * @param key  键
     * @param item 项
     * @param by   要减少记(小于0)
     * @return
     */
    public double hdecr(String key, String item, long by) {
        return redisTemplate.opsForHash().increment(key, item, -by);
    }


    /****************** Map end ****************/


    /****************** Set start ****************/

    /**
     * 根据key获取Set中的所有值
     *
     * @param key 键
     * @return
     */
    public Set sGet(String key) {
        try {
            return redisTemplate.opsForSet().members(key);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 根据value从一个set中查询,是否存在
     *
     * @param key   键
     * @param value 值
     * @return true 存在 false不存在
     */
    public boolean sHasKey(String key, Object value) {
        try {
            return redisTemplate.opsForSet().isMember(key, value);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }


    /**
     * 将数据放入set缓存
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSet(String key, Object... values) {
        try {
            return redisTemplate.opsForSet().add(key, values);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }

    /**
     * 将set数据放入缓存
     *
     * @param key    键
     * @param time   时间(秒)
     * @param values 值 可以是多个
     * @return 成功个数
     */
    public long sSetAndTime(String key, long time, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().add(key, values);
            if (time > 0)
                expire(key, time);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 获取set缓存的长度
     *
     * @param key 键
     * @return
     */
    public long sGetSetSize(String key) {
        try {
            return redisTemplate.opsForSet().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 移除值为value的
     *
     * @param key    键
     * @param values 值 可以是多个
     * @return 移除的个数
     */
    public long setRemove(String key, Object... values) {
        try {
            Long count = redisTemplate.opsForSet().remove(key, values);
            return count;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


    /****************** Set end ****************/

    /****************** List start ****************/

    /**
     * 获取list缓存的内容
     *
     * @param key   键
     * @param start 开始
     * @param end   结束 0 到 -1代表所有值
     * @return
     */
    public List lGet(String key, long start, long end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }


    /**
     * 获取list缓存的长度
     *
     * @param key 键
     * @return
     */
    public long lGetListSize(String key) {
        try {
            return redisTemplate.opsForList().size(key);
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }


    /**
     * 通过索引 获取list中的值
     *
     * @param key   键
     * @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
     * @return
     */
    public Object lGetIndex(String key, long index) {
        try {
            return redisTemplate.opsForList().index(key, index);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, Object value) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, Object value, long time) {
        try {
            redisTemplate.opsForList().rightPush(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @return
     */
    public boolean lSet(String key, List value) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 将list放入缓存
     *
     * @param key   键
     * @param value 值
     * @param time  时间(秒)
     * @return
     */
    public boolean lSet(String key, List value, long time) {
        try {
            redisTemplate.opsForList().rightPushAll(key, value);
            if (time > 0)
                expire(key, time);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 根据索引修改list中的某条数据
     *
     * @param key   键
     * @param index 索引
     * @param value 值
     * @return
     */
    public boolean lUpdateIndex(String key, long index, Object value) {
        try {
            redisTemplate.opsForList().set(key, index, value);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 移除N个值为value
     *
     * @param key   键
     * @param count 移除多少个
     * @param value 值
     * @return 移除的个数
     */
    public long lRemove(String key, long count, Object value) {
        try {
            Long remove = redisTemplate.opsForList().remove(key, count, value);
            return remove;
        } catch (Exception e) {
            e.printStackTrace();
            return 0;
        }
    }
    /****************** List end ****************/

}
 
  

测试

登陆

使用一个权限值为20的账号登陆

springboot切面实现token权限校验_第4张图片

执行权限所需20以上的查询用户操作

获取到数据

springboot切面实现token权限校验_第5张图片

执行权限所需100以上的删除用户操作

可见提示权限不足

springboot切面实现token权限校验_第6张图片

 如果有需要请向我提问,教学相长

你可能感兴趣的:(springboot,spring,boot,mybatis,java)