浅谈vue后台管理系统权限控制思考与实践

前言

最近在开发管理系统时遇到了任何管理系统都会有的需求---权限控制,之前也遇到过这种需求,但是架构不完善导致的各种问题使得后期维护非常麻烦,这一次的方案解决了之前的种种问题,现做一次记录,当然这个架构后期可能会有坑,不过得一步一步的尝试才能发现并解决问题。

权限控制需求

因为是单页面应用,路由交给前端来控制,对于一些需要特定权限才能查看的信息的保护变得尤为重要,如果前端不做好权限校验,后端也一时疏忽,就可能就会导致数据泄露。

对于权限控制,需求大致为如下:

  1. 对于大模块的限制,比如需要通过路由跳转的模块,这时需要进行路由拦截
  2. 对于小功能的限制,比如一个按钮,如果没有特定权限,那么这个按钮就不显示

安全层面的思考

之前接手了一个管理系统,前端是将权限列表存储在storage中来实现长久储存,这种实现方式是很不可取的,因为hacker可以通过手动更改存储的信息来实现获取特定权限,甚至系统都没有做路由拦截,如果知道模块的路由,可以直接通过输入路由信息来直接跳转到特定模块。对于一些模块的权限,权限被管理员修改后也无法立即生效,所以对于这几种情况做了如下思考与实践。

权限被管理员修改后立即生效

对于这个需求,我的做法是,获取到权限列表后,将权限信息存储在 vuex store 中,并且使用getter函数,对于是否可以使用该权限进行判断,这样一旦权限数据更新,前端权限限制功能点会自动修改,从而做到权限的实时性,大致实现如下:

// vuex state.js
export default {
  userPrivileges: {
    admin: [],
    purchaser: []
  }, // 用户权限信息
}
// vuex getters.js
export default {
  canIUse: state => (role, id) => state.userPrivileges[role].includes(id)
}

// 页面具体小功能,通过 mapGetters 引入 canIUse 函数
<span v-if="canIUse('admin', 9)">{{scope.row.allocation_subtotal}}</span>

这样一来,数据存储在内存中,那么权限信息就无法轻易的被修改,同时对于权限的判断也非常简单,只需要在特定功能点传入功能点的权限id就能判断是否可以使用这个权限了。

但是将数据存储在了内存中也会遇到一个问题,页面刷新怎么办?接下来就是讲解这种情况。

刷新页面也可以进行权限判断

对于大模块的权限拦截,肯定是通过路由钩子来进行拦截的(这种实现有很多文章讲解过,这里不具体讲解),但是通过路由钩子进行拦截的前提是,权限信息得提前存在。

刷新页面会存在这种情况,页面刷新时,先执行的路由钩子,再执行的组件生命周期钩子来请求权限的列表,此时权限信息不存在,那么页面跳转到登陆页的话,体验就不够友好。

所以我的做法是,建立一个中间页,如果权限校验不通过,那么跳转至中间页,中间页进行权限的请求,请求到权限后,再判断是否可以跳转,这样的话,刷新页面体验就比较好。大致代码如下:

// vuex actions.js
// 通过返回一个promise,使得store更新与后续代码变为“同步”执行
export default {
  getUserPrivileges({ commit }) {
    return fetch.get({
      url: '/currentstaff'
    }).then(data => {
      commit('SET_USER_PRIVILEGES_INFO', data.data)
      return data.data
    }).catch(e => {

    })
  }
}
// router.js
// 需要验证权限的路由
{
  path: 'suppliers',
  component: Suppliers,
  meta: {
    role: 'admin',
    privilegeId: 5
  }
}

function isCanUseThisModule(to, from) {
  return to.matched.every(record => {
    // 利用路由meta存储相应权限信息
    if (record.meta.role) {
      return store.getters.canIUse(record.meta.role, record.meta.privilegeId)
    } else {
      return true // 如果不需要权限,直接返回true
    }
  })
}

router.beforeEach((to, from, next) => {
  if (isCanUseThisModule(to, from)) {
    next() // 权限验证通过,跳转下一路由
  } else {
    next({
      path: '/main/privilegeValidator' // 权限验证不通过时的中间页
    })
  }
})

// 权限校验中间页代码示例
created() {
  this.$store.dispatch('getUserPrivileges').then(data => {
    for (let i = 0; i < data.admin_permissions.length; i++) {
      if (this.canIUse('admin', data.admin_permissions[i])) {
        this.$router.push({
          path: this.routerList.find(value => value.privilegeId === data.admin_permissions[i]).linkHref
        })
        return
      }
    }
    this.$router.push('/login') // 如果没有任何权限,则跳转登陆页面
  })
}

用户在登陆后也可以跳转到这个权限中间页,进行权限判断后再跳转到对应模块。

尾声

大致的实现过程就是这样,希望对大家有所帮助,如果有暗坑还请指出。也希望大家多多支持我们。

(0)

相关推荐

  • vue权限管理系统的实现代码

    后台管理系统一般都会有权限模块,用来控制用户能访问哪些页面和哪些数据接口.大多数管理系统的页面都长这样. 左边为菜单,分为两级,右边为图表显示区域,有增删改查的按钮. 表的结构 SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for t_auth_rule -- ---------------------------- DROP TABLE IF E

  • 详解Vuex管理登录状态

    又仔细看了一遍vuex的文档,还是云里雾里的,不过至少明白它是一个专门管理状态的,根据数据状态的改变可以驱动视图更新,既然是这样那至少登录注册是一种状态,就用登录来做测试,学习vuex,不过话说回来,既然专门管理状态,那我至少要仔细推敲一下这个learn的学习项目有那些状态逻辑. 1.据说储存的vuex store里面的状态是临时的,右键刷新一下页面这些状态就销毁了(这是据说,请大神解惑我也没办法证实),如果是这样的话,我的用户状态user还是应该要写入sessionStorage,不然登录了的

  • vue中如何实现后台管理系统的权限控制的方法示例

    一.前言 在广告机项目中,角色的权限管理是卡了挺久的一个难点.首先我们确定的权限控制分为两大部分,其中根据粒的大小分的更细: 接口访问的权限控制 页面的权限控制 菜单中的页面是否能被访问 页面中的按钮(增.删.改)的权限控制是否显示 权限控制是什么 在权限的世界里服务端提供的一切都是资源,资源可以由请求方法+请求地址来描述,权限是对特定资源的访问许可,所谓权限控制,也就是确保用户只能访问到被分配的资源.具体的说,前端对资源的访问通常是由界面上的按钮发起,比如删除某条数据:或由用户进入某一个页面发

  • 使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一)

    1. 根据官方指引,构建项目框架 # 安装vue $ cnpm install vue@2.1.6 # 全局安装 vue-cli $ cnpm install --global vue-cli # 创建一个基于 webpack 模板的新项目my-project $ vue init webpack my-project # 进入项目目录 $ cd my-project # 安装依赖,走你 $ cnpm install # 运行项目 $ cnpm run dev 2. 运行项目之后,会看到以下界面

  • 详解使用VUE搭建后台管理系统(vue-cli更新至3.0)

    最近还没来得及更新文章,就发现vue-cli已经更新到3.0版本了. //想了想还是用升级吧,反正最终都逃不掉,不如在这个项目上实验一下3.0的威力(并不会). 升级vue-cli npm install -g vue@cli vue -V 使用图形化界面创建项目 这里需要到自定义目录下,方便以后的项目管理:执行命令后,会打开一个localhost:8080的窗口,是vue项目的图形化管理界面 cd targetFolder vue ui 创建新项目 这里不一一介绍了,随便截了两张图看看 这里配

  • 详解vue后台系统登录态管理

    技术应用 js-cookie + vuex + localStorage 做数据持久化 js-cookie npm i js-cookie --save vuex user.js import { login, logout } from '@/servers/login' import { getToken, setToken, removeToken } from '@/utils/auth' // 这是上面的js-cookie暴露出来的方法 const user = { state: {

  • vue+express 构建后台管理系统的示例代码

    一个vue+express 构建的后台管理系统 说明: vue+express 构建的后台管理系统,包括登录.注册.表格的增删改查 github 在线 搭建vue项目: 1.安装vue-cli脚手架 npm install -g vue-cli 2.创建基于webpack模版的项目 vue init webpack my-express 3.安装包依赖并运行 cd my-express npm install npm run dev vue项目基于iview-admin改造的 通过应用生成器工具

  • 使用vue.js2.0 + ElementUI开发后台管理系统详细教程(二)

    在上篇文章给大家介绍了使用vue.js2.0 + ElementUI开发后台管理系统详细教程(一) 1. 引入路由工具vue-router,切换视图 # 安装vue-router cnpm install vue-router --save-dev 2. 使用vue-router main.js import Vue from 'vue' import App from './App' import VueRouter from 'vue-router' import routeConfig f

  • 浅谈vue后台管理系统权限控制思考与实践

    前言 最近在开发管理系统时遇到了任何管理系统都会有的需求---权限控制,之前也遇到过这种需求,但是架构不完善导致的各种问题使得后期维护非常麻烦,这一次的方案解决了之前的种种问题,现做一次记录,当然这个架构后期可能会有坑,不过得一步一步的尝试才能发现并解决问题. 权限控制需求 因为是单页面应用,路由交给前端来控制,对于一些需要特定权限才能查看的信息的保护变得尤为重要,如果前端不做好权限校验,后端也一时疏忽,就可能就会导致数据泄露. 对于权限控制,需求大致为如下: 对于大模块的限制,比如需要通过路由

  • 浅谈Vue SPA 首屏加载优化实践

    写在前面 本文记录笔者在Vue SPA项目首屏加载优化过程中遇到的一些坑及优化方案! 我们以 vue-cli工具为例,使用 vue-router搭建SPA应用,UI框架选用 element-ui, ajax方案选用 axios, 并引入vuex,使用 vuex-router-sync将 router 同步到 store ,服务器使用本地Nginx服务. 构建项目 vue-init webpack vue-spa-starter-kit cd vue-spa-starter-kit npm ins

  • 浅谈vue权限管理实现及流程

    一.整体思路 后端返回用户权限,前端根据用户权限处理得到左侧菜单:所有路由在前端定义好,根据后端返回的用户权限筛选出需要挂载的路由,然后使用 addRoutes 动态挂载路由. 二.实现要点 (1)路由定义,分为初始路由和动态路由,一般来说初始路由只有 login,其他路由都挂载在 home 路由之下需要动态挂载. (2)用户登录,登录成功之后得到 token,保存在 sessionStorage,跳转到 home,此时会进入路由拦截根据 token 获取用户权限列表. (3)全局路由拦截,根据

  • 基于Vue实现后台系统权限控制的示例代码

    用Vue/React这类双向绑定框架做后台系统再适合不过,后台系统相比普通前端项目除了数据交互更频繁以外,还有一个特别的需求就是对用户的权限控制,那么如何在一个Vue应用中实现权限控制呢?下面是我的一点经验. 权限控制是什么 在权限的世界里服务端提供的一切都是资源,资源可以由请求方法+请求地址来描述,权限是对特定资源的访问许可,所谓权限控制,也就是确保用户只能访问到被分配的资源.具体的说,前端对资源的访问通常是由界面上的按钮发起,比如删除某条数据:或由用户进入某一个页面发起,比如获取某个列表数据

  • 浅谈vue获得后台数据无法显示到table上面的坑

    因为刚学vue然后自己自习了一下axios,然后想写一个简单的查询后台数据 <tr v-for=" user in uList"> <td>{{user.id}}</td> <td>{{user.name}}</td> <td>{{user.gender}}</td> </td> </tr> 然后先是写了这样一个代码 created: function () { axios.ge

  • 浅谈vue中document.getElementById()拿到的是原值的问题

    问题 两个界面都有id="test"的div,内容不同,路由切换的时候document.getElementById()拿到的是原界面的值. 问题代码 // 页面1 <div id="test">aaa</div> // 页面2 <div id="test">bbb</div> // 路由切换如下: <transition name="card-fade"> <

  • 浅谈vue websocket nodeJS 进行实时通信踩到的坑

    先说明,我并不知道出现坑的原因是什么.我只是按照别人的写法就连上了. 我的处境是这样的 我的前台是用了 vue 全家桶,启动了一个 9527 端口. 而我的后台是用 nodeJS,启动了 8081 端口. 很明显,这种情况就出现了头疼的跨域. 贴出我的代码,如下 server.js(后台) var app = express(); var server = require('http').createServer(app); var io = require('socket.io')(serve

  • vue实现菜单权限控制的示例代码

    大家在做后台管理系统时一般都会涉及到菜单的权限控制问题.当然解决问题的方法无非两种--前端控制和后端控制.我们公司这边的产品迭代速度较快,所以我们是从前端控制路由迭代到后端控制路由.下面我会分别介绍这两种方法的优缺点以及如何实现(不熟悉vue-router API的同学可以先去官网看一波API哈). 我先简单说下项目的需求:如下图所示,有一级菜单和二级菜单,然后不同的人登录进去会展示不同的菜单. 前端控制路由的思路:将所有的路由映射表都拿到前端来维护,就是我的router.js里面将所有的菜单p

  • 浅谈Vue灰度发布新功能的使用

    目录 概述 组件级别 页面级别 方案一 新增入口页面分发 方案二 高阶组件方案 方案三 动态Router.js引入 总结 参考 什么是灰度发布?百度百科的解释如下. 灰度发布是指在黑与白之间,能够平滑过渡的一种发布方式.AB test就是一种灰度发布方式,让一部分用户继续用A,一部分用户开始用B,如果用户对B没有什么反对意见,那么逐步扩大范围,把所有用户都迁移到B上面来.灰度发布可以保证整体系统的稳定,在初始灰度的时候就可以发现.调整问题,以保证其影响度. 从上可以看出,灰度发布的主要作用有以下

  • 浅谈Vue Element中Select下拉框选取值的问题

    之前写了.一个原生的select的,因为展示效果原因,给删除掉了,忘记保存代码了,现在大家展示使用elementUI的下拉框封装一个组件,供咱们项目中经常调用,减少代码量. html: <el-select v-model="ite" placeholder="请选择" value-key="mateGroup"> <el-option style="width: auto" :disabled="

随机推荐