一、前言
在广告机项目中,角色权限管理是一个长期被卡住的难点。首先,我们确定的权限控制分为两个部分,根据颗粒的大小更详细:
界面访问权限控制页面权限控制菜单页面是否可以访问(添加、删除、更改)显示页面中的权限控制,我们来看看这些权限控制是如何实现的。
二、接口的访问控制
界面权限是对用户的验证。通常,服务器需要在用户登录时向前台返回一个Token,然后前台每次调用接口时都需要带上这个Token。
然后服务器获得这个令牌并进行比较。如果通过,就可以访问。
现有的做法是将后台返回的Token直接存储到sessionStorag e中,例如在成功登录的回调中,但是在请求时,取出Token并将其放入标头中,然后将其传递给后台。代码如下:
这个。$http({ method: 'get ',url: 'test/query?id=20 ',true为Credentials:header RS : { token : session storage . getitem(' token '),Name: SessionStorage。getitem(' name ')//响应后台需求传递的用户名} })。然后(response={//请求成功后的操作})后来在一些文章中发现,axios可以直接将Token插入到拦截器中的config.headers.Authorization中,作为全局传入。以下是代码部分:
//main.js从' axios'/导入Axios/实例化Axios并设置超时const service=Axios . create({ timeout : 5000 })//base URL//Axios . defaults . base URL=' https://API . github.com ';//http请求拦截器//每个请求都会在http头中添加一个Authorization字段,其内容为tokenservice。拦截器。request.use (config={if (store。state.user.token) {config。headers . authorization=` token $ { store。state . user . token } `;}返回配置},err={ return Promise . reject(err)});导出默认服务三。页面权限控制
如前所述,页面权限控制分为两种类型:
菜单中的页面是否可以访问是由页面中按钮(添加、删除和更改)的权限控制的。一般这些权限都是在固定页面上配置,保存后记录在数据库中。
抛开按钮权限不谈,页面访问权限在实现上可以分为两种方式:
显示所有菜单。当用户访问不在他或她自己权限内的菜单时,他或她会提示权限不足,并且只显示当前用户可以访问的权限内的菜单。如果用户通过URL强制访问,他或她将直接进入404。既然他或她被展示后不能点击,那逗我开心是什么意思?所谓“眼不见,心不烦,心不烦”,综合考虑,绝对是符合良好用户体验的第二个方案。
好了,现在让我们整理一下页面访问的一般流程:
整理完流程后,我们开始详细写。
1.创建路由表
其实创建路由表并不难,只要按照vue-router官方文档给出的例子就行了。但是因为有些页面不需要访问权限,
因此,有必要将登录、404、维护和其他页面写入默认路由,并将需要权限的其他页面写入变量或文件,这可以
从而有效降低后续维护压力。
粘贴下面index.js的代码,异步路由会减少,避免占用太多空间。
//路由器/索引。jsimport Vue从' Vue '导入路由器从' Vue-Router '导入应用程序从' @/App '导入存储从'./store/index ' vue。使用(路由器);//手动跳转的页面白名单常数白名单=['/'];//默认不需要权限的页面const constantroutermap=[{ path : '/',name: '登录,组件:(解析)=require([' @/组件/登录'],resolve) },{ path: '/index ',name: 'nav .Home ',组件:(解析)=require([' @/components/index '],resolve) },{ path: '/templateMake ',name: '模板制作,组件:(解析)=require([' @/components/Template/Template make '],resolve) },{ path: '/programMack ',name: '节目制作,组件:(解析)=require([' @/components/Template/programMack '],resolve) },{ path: '/release ',name: '节目发布,组件:(解析)=要求([' @/组件/程序/版本'],解析)}]//注册路由导出常量路由器=新路由器({ routes : constantrotermap });//异步路由(需要权限的页面)导出const AsyncRouterMap=[{ path : '/resource ',name: 'nav .Resource ',meta : { permissions :[]},component :(resolve)=require([' @/components/resolve ']),resolve },{ path: '/template ',name: 'nav .Template ',meta : { permissions :[]},component :(resolve)=require([' @/components/Template/Template '],resolve) },{ path: '/generalSet ',name: 'nav .System ',meta 3: { permissions :[]},component :(resolve)=require([' @/components/system et/general set '],resolve) },{ path: ' ',name: 'nav .日志,组件:应用程序,子级:[{ path : '/用户日志,名称: '导航UserLog ',meta 33: { permissions :[]},component :(resolve)=require([' @/components/Log/user Log '],resolve),},{ path: '/operatingLog ',name: 'nav .SystemLog ',meta : { permissions :[]},components :(resolve)=require([' @/components/Log/operating Log '],resolve)},]}];注意事项:这里有一个需要非常注意的地方就是404 页面一定要最后加载,如果放在constantrouttermap一同声明了404,后面的所以页面都会被拦截到404,详细的问题见当404的通配符路由无效时,添加路由
2、页面访问权限
在开始时我们梳理了一个大致的页面访问权限流程。下面我们先实现最核心的部分:
我们首先获取用户权限列表,在这里我们将接触到状态管理状态管理,官方文档有详细介绍,这里就不过多描述了,下面请看代码:
//存储/索引。jsimport Axios从' Axios '导入Vue从' Vue '导入Vuex从' Vuex '导入Vue。使用(Vuex);const axios=Axios。create();const state={ mode: 'login ',list :[]};const getter={ };常数突变={ setMode:(状态,数据)={ state.mode=data },setList:(状态,数据)={ state.list=data } }常量操作={ //获取权限列表getPermission({ commit }){ 0返回新的承诺(解析,拒绝)={ axios({ URL : '/特权/queryPrivilege?id=' sessionstorage。getitem(' privId '),methods: 'get ',标头RS : { token : session storage。getitem(' token '),名称: sessionstorage。getitem(' name ')} }).然后((res)={ //存储权限列表提交(' setList ',RES . data)。卡斯特。优先级[0]).儿童);解析数据。卡斯特。优先级[0]).儿童)})。catch(()={ reject()})};导出默认的新Vuex .存储({状态、突变、动作、获取器})好了,我们现在请求后台拿到了权限数据,并将数据存放到了状态管理中,下面我们需要利用返回数据匹配之前写的异步路由表,将匹配结果和静态路由表结合,开成最终的实际路由表。
其中最关键的是利用vue-router2.2.0版本新添加的一个添加路由方法,我们看看官方文档如何解释此方法的:
router.addRoutes(路由)2.2.0动态添加更多的路由规则。参数必须是一个符合路线选项要求的数组。
那我们现在就可以开始使用添加路由进行路由匹配了。下面看代码:
//router/index.js/** *根据权限匹配路由* @param {array}权限权限列表(菜单列表)* @param {array} asyncRouter异步路由对象*/函数routerMatch(权限,异步路由器){返回新的Promise((解析)={ const routers=[];//创建路由函数createRouter(权限){ //根据路径匹配到的路由器对象添加到路由器中即可允许。foreach((项)={ if(项。子项目。孩子们。长度){ createRouter(项。儿童)}让路径=item.path//循环异步路由,将符合权限列表的路由加入到路由器中异步路由器。查找((s)={ if(s . path==' '){ s . children。find((y)={ if(y . path===path){ y . meta。权限=项目。许可;路由器。推动;} })} if(s . path===path){ s . meta。权限=项目。许可;路由器。推动;} }) }) } createRouter(权限)解析([路由器]) })然后我们编写导航钩子
//路由器/索引。jsrouter。在每((to,form,next)={ if(会话存储)之前。getitem(' token '){ if(to。路径==='/'){路由器。替换('/index ')} else { console。日志(存储。国家。名单。长度);if(商店。国家。名单。长度===0){//如果没有权限列表,将重新向后台请求一次store.dispatch('getPermission ').然后(res={ //调用权限匹配的方法路由匹配(res,asyncRouterMap).然后(res={ //将匹配出来的权限列表进行添加路由路由器。添加路由(RES[0]);下一个(to.path) }) }).catch(()={路由器。替换('/')})} else { if(to。匹配。length){ next()} else { router。替换('/')} } } else { if(白名单。索引属于(到)。path)=0){ next()} else { router。替换('/')});到这里我们已经完成了对页面访问的权限控制,接下来我们来讲解一下操作按扭的权限部分。
四、数据操作权限
是否还记得前面的路由配置中我们多出来的一个代码,下面我们拿出来看看:
//异步路由(需要权限的页面)导出const AsyncRouterMap=[{ path : '/resource ',name: 'nav .Resource ',meta : { permissions :[]},component :(resolve)=require([' @/components/resolve ']),resolve },{ path: '/template ',name: 'nav .Template ',meta : { permissions :[]},component :(resolve)=require([' @/components/Template/Template '],resolve) },{ path: '/generalSet ',name: 'nav .System ',meta 3: { permissions :[]},component :(resolve)=require([' @/components/system et/general set '],resolve) },{ path: ' ',name: 'nav .日志,组件:应用程序,子级:[{ path : '/用户日志,名称: '导航UserLog ',meta 33: { permissions :[]},component :(resolve)=require([' @/components/Log/user Log '],resolve),},{ path: '/operatingLog ',name: 'nav .SystemLog ',meta : { permissions :[]},components :(resolve)=require([' @/components/Log/operating Log '],resolve)},]}];为每个路由页面增加自指的字段。在routerMatch函数中将匹配到的详细权限字段赋值到这里。这样在每个页面的途径对象中就会得到这个字段。
异步路由器。查找((s)={ if(s . path==' '){ s . children。find((y)={ if(y . path===path){//赋值y . meta。权限=项目。许可;路由器。推动;} })} if(s . path===path){ s . meta。权限=项目。许可;路由器。推动;} })接下来我们编写一个某视频剪辑软件自定义指令对页面中需要进行鉴权的元素进行判断,比如类似这样的:
a @ click=' upload ' v-allow=' 3 ' '/a/* 3代表一个上传权限的身份证,权限中有3则显示按钮*/我们直接注册一个全局指令,利用虚拟节点来访问某视频剪辑软件的方法。代码如下:
//main.js//按下权限命令vue.directive ('allow ',{inserted: (El,binding,vnode)={ let permission list=vnode . context . $ route . meta . permission;if(!权限列表。包括(绑定。值){el。parentnode。removechild (el)}})到目前为止,权限控制流已经完全结束。最后,让我们看看完整的权限控制流程图。
动词(verb的缩写)路线控制完整流程图
不及物动词参考
Vue ElementUI对后台管理网站的权限控制
手把手,用vue“后台”的权威带你去掌控
以上就是本文的全部内容。希望对大家的学习有帮助,支持我们。