SpringBoot基础-权限管理2

创建项目

创建SpringBoot项目,编写登录接口,实现拦截器

创建自定注解

  • 创建annotation.Permission 注解接口
package com.qcby.annotation;

@Target(ElementType.METHOD) //注解用于字段上
@Retention(RetentionPolicy.RUNTIME) // 保留到运行时,可通过注解获取
public @interface Permission {
    String value() default "";
}

权限分配(方法二)

  • 数据库创建permission,ref_user_permission 表
CREATE TABLE `permission` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `url` varchar(255) COLLATE utf8mb4_bin DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

CREATE TABLE `ref_user_permission` (
  `user_id` bigint(20) NOT NULL,
  `permission_id` bigint(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
  • 编辑MenuMapper接口,添加getPermissionListById方法
public interface MenuMapper {
    public Set<String> getPermissionListById(@Param("id") Long id);
}
  • 编辑MenuMapper.xml,添加getPermissionListById方法
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qcby.mapper.MenuMapper">
    <select id="getPermissionListById" resultType="java.lang.String">
        select url from permission left join ref_user_permission
                    on permission.id=ref_user_permission.permission_id
        where ref_user_permission.user_id=#{id}
    </select>
</mapper>
  • 编辑MenuService接口,添加getPermissionListById方法
public interface MenuService {
    public Set<String> getPermissionListById(Long id);
}
  • 编辑MenuServiceImpl类,实现getPermissionListById方法(根据用户id获取权限)
@Service
public class MenuServiceImpl implements MenuService {
    @Resource
    private MenuMapper menuMapper;
   
    @Override
    public Set<String> getPermissionListById(Long id) {
        return this.menuMapper.getPermissionListById(id);
    }
}
  • 给想要分配权限的方法加上注解
    @Permission("student")//自定义注解
    @GetMapping("getUsers")
    public List<User> getUsers(){
        return this.service.list();
    }
  • 编辑UserController中的登录方法
package com.qcby.controller;

@RestController
@RequestMapping("login")
public class UserController {
    @Autowired
    private UserServiceImpl service;
    @Autowired
    private HttpSession session;
    @Autowired
    private MenuServiceImpl menuService;

    @RequestMapping(value = "login",method = RequestMethod.GET)
    public Map<String,Object> login(User user){
        Map<String,Object> map = new HashMap<>();
        map.put("code",0);
        if(StringUtils.isEmpty(user.getUsername()) || StringUtils.isEmpty(user.getPassword()) ){
            map.put("msg","用户或者密码为空!");
            return map;
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("username",user.getUsername())
                .eq("password",user.getPassword());
        User userDb = service.getOne(queryWrapper);
        if(userDb != null){
            map.put("code",1);
            map.put("data",userDb);
            /*session.setAttribute("username",userDb.getUsername());*/

            String token= TokenUtil.generateToken(userDb);
            map.put("qcby-token",token);
            // *重点*
            //调用getPermissionListById方法获取登陆的用户的所有权限,放到User
            //实体类的url属性里面
            Set<String> url=menuService.getPermissionListById(userDb.getId());
            userDb.setUrl(url);
        }else{
            map.put("msg","用户名或密码错误!");
        }
        return map;
    }


    @Permission("student")//自定义注解
    @GetMapping("findAll")
    public List<User> findAll(){
        return this.service.findAll();
    }
}
  • 编辑LoginInterceptor拦截器,实现通过注解分配角色
package com.qcby.interceptor;

public class LoginInterceptor implements HandlerInterceptor {
    private Logger log = LoggerFactory.getLogger(getClass());
    @Autowired
    private HttpSession httpSession;
    //Controller逻辑执行之前
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("preHandle....");
        String uri = request.getRequestURI();
        System.out.println("uri:"+ uri);

         /* HandlerMethod=>Controller中标注@RequestMapping的方法
         *  需要配置静态资源不拦截时,添加这块逻辑  => 前后端分离项目
         */
        if (!(handler instanceof HandlerMethod)) {
            return true;
        }
        String token=request.getHeader("qcby-token");
        if (!TokenUtil.verify(token)) {
            // 未登录跳转到登录界面
            response.sendRedirect("/login/login");
            return false;
        }else {
            //登录成功
            HandlerMethod handlerMethod=(HandlerMethod)handler;
            //通过反射获取用户访问的接口的自定义注解
            Permission permission=handlerMethod.getMethodAnnotation(Permission.class);
            //如果注解不为null
            if(permission!=null){
                //获取用户信息
                User user=TokenUtil.getUser(token);
                //获取用户url属性
                Set<String> url=user.getUrl();
                //自定义注解的值存在于url集合里面
                if(url.contains(permission.value())){
                    //允许访问
                    return true;
                }else {
                    //注解的值不在集合里面,不允许访问
                    //throw new Exception("权限不足");
                    return false;
                }
            }else {
                //如果注解为null,不允许访问
                return false;
            }
        }
    }

    //Controller逻辑执行完毕但是视图解析器还未进行解析之前
    @Override
    public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, ModelAndView modelAndView) throws Exception {
        System.out.println("postHandle....");
    }

    //Controller逻辑和视图解析器执行完毕
    @Override
    public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) throws Exception {
        System.out.println("afterCompletion....");
    }
}

源码

仓库中demo0327是源码 稍加修改即可运行

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值