前言
作为一个前端开发,我们有时候会遇到一些没有权限访问的页面,或者通过点击某个按钮但却没有权限。鉴于自己遇到了这样的问题,所以在这里做一个总结
需求分析
系统管理员能够进入角色页面,并且通过功能权限或者页面权限给用户分配权限,包括用户是否有权限访问某个页面,或者是通过编辑以及添加这种操作进入某个页面,如下图所示。


可以看到第二张图,我们给这个角色为测试的用户,对某个页面的功能进行了权限设置,点击确定后,角色为测试的用户将无法使用该页面的编辑以及新增功能。

但到这里还不算真正的达到了权限控制,这里我们只是通过对编辑以及新增这两个功能进行了权限控制,从而阻止用户进入编辑或者新增页面。
实际上, 既然我们不能通过点击的方式进入页面,那我们能不能直接通过路由的方式直接访问呢?答案是如果我们没有做路由权限的控制,那就是可以的。
也就是说,就算我不能通过点击编辑或者新增进入页面,但只要我知道编辑或者新增的页面对应的url, 我就能够访问到这个页面。
因此我们必须从两个方面对页面进行权限控制。 因为通过点击进入页面的方式已经做了权限控制了,那么剩下的就是限制通过url来访问页面了。
第一步, 点击操作(编辑或者新增)的权限是如何控制的
这个应该根据后端接口返回的数据结构来决定, 比方说后端现在返回给我一个这样的数据结构
{
code: 0,
data: [{
comment: '编辑', // 功能名称
checkStatus: false // 功能权限
}, {
comment: '新增',
checkStatus: true
}]
}
对应的编辑页面的route
routes: [{
name: 'article-edit',
path: '/article/edit',
beforeEnter: (to, from, next) {
http.get(apis.getButtonsPowerList, {
params: {
pageId: xxxx
}
}).then(res => {
if(res.code === 0) { // code为0说明请求成功
let btnsPowerList = res.data // 获取按钮权限列表
for(let i = 0; i < btnsPowerList.length; i++) {
if(btnsPowerList[i].comment === '编辑') { // 找到comment为编辑的按钮
if(btnsPowerList[i].checkStatus) { // 判断编辑按钮的checkStatus是否为true
next() // 如果为true,表示有权限,则进入相应页面
} else { // 否则提示用户没有访问权限,并且退回上一页面
setTimeout(() => {
window.history.go(-1)
})
alert('您没有访问该页面的权限')
}
}
}
}
})
}
}]
从上述代码来说,功能是实现了,但是像这样的控制页面权限的功能,我们需要将其封装起来,否则会造成大量的代码冗余。所以下面是封装之后的代码。
export function isAuthRoute(comment, pageId, next) {
new Promise(resolve => {
_isAuth(comment, pageId, resolve)
}).then(res => {
if(!res) {
setTimeout(() => {
window.history.go(-1)
}, 1500)
alert('您没有访问该页面的权限')
} else {
next()
}
})
}
function _isAuth(comment, pageId, callback) {
http.get(apis.getButtonsPowerList, {
params: {
pageId
}
}).then(res => {
if(res.code === 0) {
let btnsPowerList = res.data
for(let i = 0; i < btnsPowerList.length; i++) {
if(btnsPowerList[i].comment === comment) {
callback(btnsPowerList[i].checkStatus)
}
}
}
})
}
调用的方式也很简单
routes: [{
name: 'article-edit',
path: '/article/edit',
beforeEnter: (to, from, next) {
isAuthRoute('编辑', pageId, next)
}
}]
注意,以上的调用接口的方式以及传参的内容,需要根据自身的需求来决定
总结
其实这部分的代码,最多只是提供了一个思路,因为不同的场景肯定写出来的代码也是不一样的。在这个需求当中,我学习到的东西更多的是一个执行顺序的问题,我们知道文中使用的 beforeEnter 会在进入页面之前调用,但是请求数据的接口是异步的, 而我们需要通过异步接口返回的数据来判断是否有权限进入页面,这意味着我们必须先拿到数据再去做判断,所以这个时候我们更希望保持一个同步的顺序,所以这里才使用了promise,由于promise中的then中的回调函数必须等到resolve后才会被执行, 因此我们将resolve作为参数传递给真正调用了接口的函数, 直到接口返回数据之后,再在接口请求完毕的回调里面调用resolve,通过这样的方式,就能够确保在做权限判断的时候,一定能够拿到数据。
最后,如果能够帮到各位,请不要吝惜点赞哦,谢谢。
以上的内容来自于我的csdn博客,因为没啥人看,就搬过来掘金了。 我的csdn地址: blog.csdn.net/huangguangy…