基于导航守卫实现页面的权限控制

前言前端

做为一个前端开发,咱们有时候会遇到一些没有权限访问的页面,或者经过点击某个按钮但却没有权限。鉴于本身遇到了这样的问题,因此在这里作一个总结后端

需求分析api

系统管理员可以进入角色页面,而且经过功能权限或者页面权限给用户分配权限,包括用户是否有权限访问某个页面,或者是经过编辑以及添加这种操做进入某个页面,以下图所示。 promise

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

到这里还不算真正的达到了权限控制,这里咱们只是经过对编辑以及新增这两个功能进行了权限控制,从而阻止用户进入编辑或者新增页面。数据结构

实际上, 既然咱们不能经过点击的方式进入页面,那咱们能不能直接经过路由的方式直接访问呢?答案是若是咱们没有作路由权限的控制,那就是能够的。异步

也就是说,就算我不能经过点击编辑或者新增进入页面,但只要我知道编辑或者新增的页面对应的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…

相关文章
相关标签/搜索