RBAC基本流程实现

RBAC中最重要的一个名词是role角色,项目中每个账号的权限不同,所以看到的东西,可以做的操作是不一样的,所以引入这个是非常有必要的,下面图中是5个表的实现,但是为了方便理解,用户表——角色表省去了,就意味着每个用户只能对应一种角色,是一对一的关系,用主外键实现。在这里插入图片描述
首先,把登录功能实现,因为比较基本,这里不一一赘述,因为用户表中的type是外键,就是角色表中的rid主键,就意味着用户只要登录上去就可以得到用户是什么角色,接下来的工作就是根据角色查出来这个角色在菜单表里面可以有什么操作,这里的菜单表也是权限中的内容。这个SQL语句是个多个操作select * from menu where mid in(select mid from role_menu where rid = #{param1}) and pid = #{param2}
显然这里需要两个参数,一个是角色中的rid,另外一个是pid这是菜单表中的自连接的父id,这里用了二级目录,pid是上级目录的mid(自联查询条件)。下面是接口的具体实现

@Service
public class MenuServiceImpl implements MenuService {
    @Autowired
    private MenuMapper menuMapper;
    @Override
    public List<Tree> selectTree(int rid, int pid) {
        List<Menu> menus = menuMapper.selectMenu(rid, pid);
        List<Tree> list = new ArrayList<>();
        for (Menu m:menus) {
            Tree tree = new Tree(m.getMid(),m.getMname(),m.getStatus()==0?"closed":"open",m.getUrl());
            list.add(tree);
        }
        return list;
    }
}

这里用的SSM框架+easyUI实现,因为前端接收的数据就写死的三个值,所以就用了另外一个实体类Tree来接收Menu类中数据,我这里接收了四个,因为后面要用到。这就是Service层要做的事情,接下来写Controller。

@RestController
@RequestMapping("/MenuController")
public class MenuController {
    @Autowired
    private MenuService menuService;
    @RequestMapping("/findMore")
    public List<Tree> findMore(@RequestParam(defaultValue = "0") int id, HttpSession httpSession){
        User user = (User) httpSession.getAttribute("user");
        return menuService.selectTree(user.getRid(),id);
    }
}

这里就需要考虑两个参数的问题了,前端只传过来一个id,这个id就是我们需要pid,这是前端框架根据几级目录给我们传的参数,我们直接赋给第二个参数即可,第一个参数的rid我们无法从前面获得,这时候就想到我们登录的时候,就可以把rid确定下来,这时候就用到了session来保存我们已经登录的session对象,把登录的user保存到session中,再在我们这里get到这个session对象, 用这个对象的rid来给我们需要的第一个参数赋值。到这里我们就实现了基于角色的菜单的显示。但是Bug非常多,下面一一解决。
第一:我们这里不登录,直接访问main.jsp是可以访问的,这就需要引入过滤器来实现,这里又要用到那个session对象 ,只要session为null,他访问别的之后,让他调转到登录页面。
第二:用户登录上以后,长时间不操作,sessio失效了,然后用户发送Ajax请求去访问别的页面,也是可以访问的,这明显是不允许的,所以这里就要再次拦截它,回到登录页面。
第三:这样虽然实现了,菜单栏显示的内容不一样,但是当普通用户登录后,而他正好知道管理员的部分的URL,这样也是可以访问的,这里也是不允许的,然后就需要引入另外两张表,URL表和role—url表,URL表也算是权限的一部分,有两个字段组成,一个是uid,一个是uname就是可以访问的路径,因为是多对多的关系,所以引入中间表,下面是mapper的实现,

public interface URLMapper {
    @Select("select uname from url where uid in (select uid from role_url where rid = #{param1})")
    List<String> selectURL(int rid);
}

这里的sql语句和上面类似,用户登录以后,就可以拿到rid,这里就需要一个集合来存放这个用户可以登录的那些地址,所以选择了在user实体类中,多了一个list类型的属性,来存放地址们,Usercontroller代码如下

@RestController
@RequestMapping("/UserController")
public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private URLService urlService;
    @RequestMapping("/findUsers")
    public int findUsers(String zh, String pwd, HttpSession httpSession){
        User user = userService.findUser(zh, pwd);
        if (user!=null){
            //当前登录用户的所有权限,然后在过滤器里面验证是否包含在里面
            List<String> url = urlService.findURL(user.getRid());
            user.setURL(url);
            httpSession.setAttribute("user",user);
            return 1;
        }else {
            return 0;
        }
    }
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值