zoukankan      html  css  js  c++  java
  • 关于项目权限的改造

    项目背景:权限分配是通过用户、角色 、菜单、数据权限、分配的。通过给用户设置不同的角色。通过给不同角色设置不同菜单。同事在给角色设置菜单的时候设置菜单的数据权限。

    比如:张三分配报销角色,报销角色分配申请单、报销单按钮。在分配菜单的时候,给张三设置申请单和报销单的数据权限。我们项目设置的数据权限有组织、公司、公司及其子公司、部门、部门及其下属部门,个人 。来实现不同级别的人可以看到的数据权限不同。

    因为设计了数据权限功能所以每次数据查询都需要先查数据的权限。 数据的权限是通过 用户与角色表关联表,角色与菜单关联表 菜单与权限关联表,查询到该用户设置的权限为组织、公司、部门等的时候,再去查组织、或公司、部门下的人员的id。开始的时候因为数据量少,满足用户的需求。一段时间后,因为使用的公司越来越多和系统越来越庞大。每个接口的响应时间越来越慢, 后来我们排查,是因为查询数据权限的的方法耗时太长,大概需要0.8s。我们就以减少查询数据权限为方向,思考解决方案。

    我们第一版解决方案:查询数据的时候不去调用查询数据权限接口。改成用户每次点击菜单,前端调用一个接口去查这个菜单的数据权限并将结果缓存到redis用户信息中的ownlist,
    用户在查询数据的时候用token去redis拿用户信息中的owenlist。当用户切换菜单的时候,ownlist也会更新。这样就减少了接口的响应时间,也减少了对数据库的查询次数。而且也保证了当用户的数据权限发生改变的时候,只要切换页面就获取到了当前页面最新的数据权限。但是也导致了一个结果,因为pc端和手机端使用的是同一个后端且同一个token。所以pc端和手机端会相互影响。

    比如我申请单的权限是全公司,我报销单的权限是个人, 我手机端打开的报销单页面,然后我pc端打开申请单,那么我手机端点击申请单查询就只能看到个人的数据了。我们的解决办法的pc端和手机端使用不同的token,。这样就不会相互影响。 但还是有一种情况就是用户在pc端开两个页面。一个页面打开报销单页面,在打开申请单页面,然后点击报销单的查询就能看到全公司的报销单数据。

    导致方案一的问题是因为每个页面拿取ownerlist都是通过token。那么优化的方向是让 每个页面获取ownerlist的key不同,当点击菜单的时候 ownerlist不放在用户信息中,单独放出来,使用菜单url+公司id+用户id 为key ownerlist为value放在redis中,用户查询数据的时候通过key去获取。这样就解决了不用页面相互影响ownerlist的问题。  因为每个页面都有单独的key,我们对owner缓存进一步优化, 当用户点击菜单在redis中没有ownerlist数据,就去数据库中查询,然后放在缓存中,下次获取的时候,直接从redis中获取。我们根据用户的操作的习惯,有个功能用户可能偶尔才使用,我们就将ownerlist的过期时间设置为一天,减少必要数据。y为解决用户获取最新数据,当权限发生改变的时候的,将redis对应的key模糊删除。这样用户查询权限的时候redis没有值,就会去数据库查询最新值。

  • 相关阅读:
    PHP学习当中遗漏的知识点
    sql必知必会(第四版) 学习笔记
    servlet 笔记
    sql server 快捷键
    233
    第 四 课 数据类型
    第三课 go语言基础语法
    第二课 go语言的结构
    第 1 课 Go 简介
    linux 学习 查看文件占用空间大小
  • 原文地址:https://www.cnblogs.com/zhongmeilin/p/15522595.html
Copyright © 2011-2022 走看看