怎么关闭手机后运行的软件电脑(后台管理系统权限管理详解)
权限管理
简述权限管理:
你可以在后台通过一个 tree 控件或者其它展现形式给每一个页面动态配置权限 ,之后将这份路由表存储到后端 。当用户登录后得到roles ,前端根据roles去向后端请求可访问的路由表 ,从而动态生成可访问页面 ,之后就是 router.addRoutes 动态挂载到router 上 ,你会发现原理是相同的 ,万变不离其宗 。和后台开发时人员商量 ,能不能在登录之后 ,把相关权限接口数据返回给我 ,然后进行菜单的动态展示
前端权限的意义
1降低非法操作的可能性
2.尽可能的排除不必要的请求,减少服务器压力
3.提高用户体验 前端权限控制思路菜单的控制(管理系统的侧边栏)
在登陆请求中 ,会得到权限数据 。当然 ,这个需要后台返回的数据的支持 ,前段根据权限数据,展示对应的菜单 ,点击菜单 ,才能查看相关的界面
界面的控制
如果用户没有登录,手动在地址栏敲入管理界面的地址,则需要跳转到登录界面
如果用户已经登录,可是手动敲入非权限内的地址,则需要跳转404界面
按钮的控制
在某个菜单的界面中,还得根据权限数据,展示出可进行操作的按钮,比如删除,修改,增加
请求和响应的控制
如果用户通过非常规操作,比如通过浏览器调试工具将某些禁用的按钮变成启腆状态,此时发的请求,也应该被前端所拦截
后台管理系统的权限管理
菜单控制
我现在登录就让后台把路由信息发给我,但是我要用到菜单 页面 ,这时候我就要使用vuex来共享路由信息;在state中写一个空数组rightList[]接收login页面提交过来的权限数据 。映射到菜单页面
当我登陆过后刷新页面时菜单栏消失 ,为什么?怎么解决
因为当我登陆过后重新加载时 ,我的vuex也被刷新 ,但是vuex的初始值我放的是一个空数组 ,而且此时我们也没有进行那个登陆操作了 。所以就导致我的rightList从有数据变成了没数据⇒我渲染的菜单栏消失 。
state:{ rightList:JSON.parse(sessionStorage.getItem(rightList)||[]) }, mutations:{ setRightList(state,data){ state.rightList = data sessionStorage.setItem(rightList,JSON.stringify(data)) } }当我点击退出之后 ,我需要清空sessionStorage和vuex中的数据 在点击登出的这个事件中除了写跳转到登录页面还要写清除操作
logout(){ //删除sessionStorage数据 sessionStorage.clear() this.$router.push(/login) //删除vuex中的数据 ,让当前的界面刷新(先跳转再刷新) window.location.reload() }界面控制
正常的逻辑是通过登录界面,登录成功之后跳转到管理平台界面,但是如果用户直接敲入管理平台的地址,也是可以跳过登录的步骤.所以应该在某个时机判断用户是否登录
如何判断用户是否登陆
在登录时把后台接口中返回的路由数据中的token存起来 , 有token就是登录 ,没就是没登录 sessionStorage.setItem(token,res.data.token)什么时机判断
使用路由导航守卫
router.beforeEach((to,from,next)=>{ if(to.path===/login){ next() }else{ const token = sessionStorage.getItem(token) if(!token){ next(/login) }else{ next() } } })还有一个问题 ,当我登陆之后 ,我在地址栏中敲下一个不属于我的权限界面 ,我依旧可以进入(例如我是一个普通用户,我不能访问角色管理界面 ,但是我在地址栏中敲下角色管理的界面地址 ,我依旧能访问)这如何阻止?
可以依旧在路由导航中继续判断,但是路由导航守卫固然可以在每次路由地址发生变化的时候,从vuex中取出rightList判断用户将要访问的界面,这个用户到底有没有权限.不过从另外一个角度来说,这个用户不具备权限的路由,是否也应该压根就不存在呢?
import store from @/store const userRoles= {path:/users,component:Users} const rolesRoles= {path:/roles,component:Roles} const goodsRoles= {path:/goods,component:Goods} const cateRoles= {path:/categories,component:Categories} 、 const ruleMapping= { users:userRoles, roles:rolesRoles, goods:goodsRoles, categories:cateRoles } { path:/home, component:Home, redirect:welcome, children:[ {path:/welcome,component:Welcome} //{path:/users,component:Users} //{path:/roles,component:Roles} //{path:/goods,component:Goods} //{path:/categories,component:Categories} ] } export function initDynamicRoutes(){ //根据二级权限 ,对路由规则进行动态的添加 const currentRoutes = router.options.routes //遍历二级权限 通过vuex中的store拿到我们的rightList数据 const rightList = store.state.rightList rightList.forEach(item=>{ item.children.forEach(item=>{ //item二级权限,动态添加到children const temp = ruleMapping[item.path] temp.meta = item.rights currentRoutes[2].children.push(temp) }) }) router.addRoutes(currentRoutes) } export default router登录成功之后动态添加
根据用户所具备的权限 ,去动态的添加路由规则(还是那个登陆里后台返回的数据) import{initDynamicRoutes }from @/router.js initDynamicRoutes()//在这个页面刷新界面之后 , //router.js这个页面当然也会重新加载 , //此时所有路由初始化 ,动态路由不复存在 , //重新登录成功之后才能使动态路由重新操作 //刷新之后我也要动态添加路由规则 这个步骤放到app.vue中在这个页面我刷新界面之后 ,router.js这个页面当然也会重新加载 ,此时所有路由初始化 ,动态路由不复存在 ,页面空白 。重新登录成功之后才能使动态路由重新操作,刷新之后我也要动态添加路由规则
我刷新之后我也要动态添加路由规则 ,我将这个放到app.vue中的created()生命周期 ,这样刷新依旧保存了路由规则
App.vue import{initDynamicRoutes }from @/router.js created(){ initDynamicRoutes () }所以initDynamicRoutes 有两个时机被调用,第一个时机是在登录成功之后被调用 ,登陆成功之后我在界面上刷新的话 ,这时候走的时候根组件当中的created的动态添加
按钮控制
虽然用户可以看到某些界面了,但是这个界面的一些按钮,该用户可能是没有权限的.因此,我们需要对组件中的一些按钮进行控制.用户不具备权限的按钮就隐藏或者禁用,而在这块中,可以把该逻辑放到自定义指令中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cmjVqZSO-1662525080962)()]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-63kHPIKH-1662525080963)()]
在按钮之上添加一个自指令
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YPMQknaP-1662525080963)()]
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ErgwxoV7-1662525080964)()]
<el-button type="primary" @click="addDialogVisible=true" v-permission="{action:add,effect:disabled}"> 添加 </el-button> 实现自定义指令=>在utils中写一个permission.js文件实现自定义指令的一个注册 import Vue from vue import router from @/router.js Vue.directive(permission,{ inserted(el,binding){ const action = binding.value.action//添加 const effect = binding.value.effect//禁用 判断当前的路由所对应的组件中,如何判断用户是否具备action的权限呢 权限的数据在rightList中;**可以做一件事情=>相关权限获取的判断** clg(router.currentRoute.meta)//看当前组件的路由规则是什么 这时候使用meta来增加这个组件这个用户所具备的权限数据 , 那么对于permission而言就方便很多很多 ,就可以解决了 if(router.currentRoute.meta.indexOf(action)===-1){ if(effect===disabled){//禁用 el.disabled=true el.classList.add(is-disabled)//ui组件需要用的样式 } el.parentNode.removeChild(el) //删除元素button } } }) 该文件在main.js中进行一个注册:import ./utils/permission.js请求和响应的控制
请求控制
除登录之外的每一次请求都需要token ,这样服务器才能鉴别你的身份 。所以在请求拦截器中写
axios.interceptors.request.use(function(req){ const currentUrl = req.url if(currentUrl!==login){ req.headers.Authorization = sessionStorage.getItem(token) } return req })如果发出了非权限内的请求,应该直接在前端访问内被阻止 ,虽然这个请求发到服务器也会被拒绝
import axios from axios import Vue from vue import router from @router.js axios.interceptors.request.use(function(req){ const currentUrl = req.url if(currentUrl !==login){ req.headers.Authorization = sessionStorage.getItem(token) const action = actionMapping[req.method] const currentRight = router.currentRoute.meta if(currentRight&¤tRight.indexOf(action)===-1){ //没有权限 alert(没有权限) return Promise.reject(new Error(没有权限))👇🏿 } //判断非权限范围内的请求 //router.currentRoute.meta //判断当前请求的行为 //restful风格请求 👇🏿 //get请求 view //post请求 add //put请求 edit //delete请求 delete //[add view edit delete]=>meta中这几种情况 通过请求方式来判断这个请求到底是做什么样的事情 , 再看一下这个事情在当前路由规则的权限列表内存不存在 ,不存在就直接阻止掉 需要映射关系=>请求方式和操作行为的映射关系 const actionMapping = { get:view, post:add, put:edit, delete:delete } } return req })响应控制
得到了服务器返回的状态码401,代表token超时或者被篡改了,此时应该强制跳转到登录界面
axios.interceptors.response.use((res)=>{ if(res.data.meta.status===401){ router.push(/login) sessionStorage.clear() window.location.reload() } return res })创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!