一个后台管理系统的设计与思考

本人通过对 ant design provue-element-admin 以及对网上后台管理系统教程的学习,得出以下观点,欢迎探讨

权限

解决方案

  • 前端方案:用户登录后返回的权限列表,通过权限列表去比对路由表,生成当前用户具有的权限可访问的路由表,通过 router.addRoutes 动态挂载到 router 上。
  • 后端方案:如果又更复杂的权限需求,比如每个页面的权限是动态配置的,则应让后端返回当前用户的路由表。

一般来说,使用前端方案就可以满足需求了,毕竟只要你开心,要整多复杂不可以?
前端方案的实现细节:

路由表:路由表是包含整个应用的所有路由,可以分为

  • 基础路由(常量路由):一些页面,比如登录、注册、404之类的页面,不需要登录就可以访问的
  • 异步路由:需要确定当前用户有权限访问才加载的路由,比如商品管理页面则需要运营的权限才加载该路由

如果是采用该前端权限方案,则路由表里面的 路由记录 需要被标记成需要什么样的权限才能访问该路由(我们这里就由是否有相应的权限来决定是否加载该路由就好了,不用角色来决定),该信息存放在路由元信息里面,也就是路由对象的 meta 属性里面,该属性是 vue-router 定义的,比如你自己定义一个 info 之类的是访问不到的。路由元信息里面一般还放一些路由标题,这样可以在面包屑里面根据路由标题列出当前的路径位置,并可以用路由标题作为 document.title。最后,路由元信息里面还可以放一个 icon,作为该菜单菜单在菜单栏里面的图标

需要考虑的细节问题:

  • 假如用户需要跳转到 A 页面,跳转的时候发现用户没有登录,于是自动跳转到登录,等用户登录后如何自动跳到 A 页面?
    记录重定向路径:
    beforeEach 之类的路由守卫在跳转到登录页面的时候,带上查询参数,类似于:/login?redirect=目标路由
next(`/login?redirect=${to.path}`)
next({ path: loginRoutePath, query: { redirect: to.fullPath } })

跳转到目标路径:
登录成功之后,查看是否有该跳转参数,有的话,就直接跳转到相应页面,否则就跳转到首页
登录成功之后,直接跳转到首页,但是路由守卫里面有设置,不管是什么路由,只要发现有跳转参数,就直接跳转到相应的路径

加载异步路由:
概述:当一个用户打开后台的首页或者某个别的后台页面,这个时候,全局路由守卫(ant design pro、vue-element-admin都用beforeEach这个api)会先检查他有没有登录,一般来说就是检查有没有 token,如果没有,则说明没有登录,会先重定向至登录页面,如果有,也不能保证 token 还依然有效,这个时候会先认为它有效,反正在进入相应的页面的时候,总会向后台发起某些请求的,请求拦截器会带上它那可能已经失效的 token,服务端也肯定会在处理请求之前,在中间件里面检查该 token 的有效性,如果无效则直接返回一个状态码,比如 401(token失效)、403(token有效,但是权限不足),后端对于一个失效的 token 规范一点来说应该返回 401而不是403,前端可以在请求响应拦截器中统一针对返回 401 的情况重定向到登录页面。总的来说,前后端为了提高效率,应共同协商好怎么处理(统一逻辑、状态码等)

访问控制模型

一般可以用 RBAC 模型,即权限跟角色相关,而不是跟某个用户直接相关,无法直接控制某个用户拥有的权限,只能控制该用户的角色,或是修改该用户的角色对应的权限。领导可能会想要这样的功能:能不能直接给某个用户添加一项权限?操作角色与权限之间的关系来控制某个用户的权限,好麻烦。这个时候,千万要慎重,不要以为直接加一个角色权限中间表就完事了,万一某一天,又给你提出一个要求,能不能单独给某个用户删除一项权限?操作角色与权限之间的关系来控制某个用户的权限,好麻烦。。。。其实说到底就是一种权衡,如果用户跟权限直接关联,灵活调整个人的权限,适合用户群体小的场景;如果用角色跟权限关联,则可以高效控制所有用户的权限,适合用户全体多的场景。

前端并不知道角色与权限之间的关系,这种关系记录在后端数据库的 角色-权限 中间表里面。前端只需要获取当前用户的权限数组即可,通过这个数组,去匹配路由表中的路由记录,最后得到当前用户的路由表,用于生成菜单。

关于权限:
权限在后端应该是以权限树的结构来体现的,也就是某个权限下面可能还有子权限,通过类似与pid的字段来关联,比如:


image.png

由此产生一个问题,如果用户只拥有 查看人员 的权限,那该用户算不算拥有人员操作的权限呢?也就是后端返回的权限数组应不应该包含 人员操作
应该说算比较合理:
(1)方便前端处理:当用户拥有查看人员的权限时,菜单肯定也要显示人员操作的这一上级菜单项
(2)逻辑更加严谨:不包含的情况下,会导致不一致的行为:如果 人员操作 里面刚开始只有 查看人员 这一项,那显然返回的权限数组就应该包含 人员操作 当添加了 更新人员删除人员之后,人员操作 就不止 查看人员 这一项了,因此后端返回的权限数组又变得不包含 人员操作 了,这回让人误以为用户的权限被编辑过,而实际上并没有。

token 的处理

token 需要有两个性质:

  • 长期性:token 根据业务需求,可能是一天过期,也可能是永久过期,所以它必须要能长期存储,不能只放在 vuex 中,这样刷新页面就没了
  • 易用性:存放在 cookie、storage里面不方便使用,为了方便存取,token 也应该放在 vuex 之类的地方,特别是根据是否有 token 来确定页面的组件是否显示

为了满足以上两点,token 应该同时存放在两种不同的地方,典型的是 storage + vuex。放在这两个地方之后,要保证它们的一致性,例如:一般不能出现 token 在 vuex 里面存在,但是在 storage 里面又不存在,或者反之。所以应该在一个函数里面同时对两个地方进行操作,ant design pro 和 vue-element-admin 是在 vuex 里面的 action 里面统一处理的

封装

什么时候需要封装:

  1. 当功能、逻辑需要复用的时候,比如:
    一个 Message、Notification 组件,虽然这些功能或许非常的简单,但是却非常常用,它们会出现在各个页面中

  2. 功能、或逻辑可能发生整体改动的时候,比如:

  • 存储 token 的实现从 cookie 改为 storage
  • 网络请求库从 axios 换成别的库

什么时候不必封装:

  • api 封装:由于 ant design pro、vue-element-admin 以及网上教程对 api 的封装无非就是返回一个 promise, 而且这种 api 很少有复用的场景,比如,一个 login api,通常只会出现在登录页面,如果其他页面也需要登录,一般都是先跳转到登录页面,登录成功之后再跳至相应页面,像 ant design pro 的一个封装的 api 函数:
export function getSmsCaptcha (parameter) {
  return request({
    url: userApi.SendSms,
    method: 'post',
    data: parameter
  })
}

请问这样的封装相比直接在页面里写有什么意义?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容