第一种:基于角色Role的动态路由管理
(不推荐,但市场用的比较多)
首先列出枚举每个角色对应几个路由,然后根据用户登录的角色遍历枚举出来的角色动态注册对应的路由
const roles = {
admin:['所有路由'],
'经理':['10个路由'],
'运营':['5个路由'],
'前台':['2个路由']
'新增一个角色':[xxx] ===>改代码重新发布版本
这种做法一个弊端:每添加一个角色,都要手动添加代码key:value。最后前端又要发布新的版本(有解决方案如下)
这种方法大致流程如下:
登录:登录验证通过之后后台会返回一个token给前端,前端会保存在vuex和本地(防止刷新丢失登录状态),然后拿token去后台请求一个userInfo的接口获取用户信息(用户名,权限信息等等)
权限验证:通过token获取用户role信息,然后根据用户role算出对应应有权限信息的路由,最后用router.addRotes动态挂载计算出的路由。
代码的实现:
根据token拿到用户信息(权限信息)
这里代码过于简单就不写了,就是请求后台的数据而已。
请求回来的数据保存在Vuex当中(actions发请求----mutations传数据给state,过程不书写了)
//箭头函数
const getDefaultState = () => {
return {
//获取token
token: getToken(),
//存储用户名
name: '',
//存储用户头像
avatar: '',
//服务器返回的菜单信息【根据不同的角色:返回的标记信息,数组里面的元素是字符串】
routes: [],
//角色信息
roles: [],
//按钮权限的信息
buttons: [],
vuex查看数据:保存成功
在获取用户信息的时候异步路由和服务器返回的路由进行对比。commit要提交对比好的路由,所有写一个对比路由函数。computedAsyncRoutes()函数第一个参数是异步路由,第二个是服务器返回的路由。
在actions外面定义一个对比路由的computedAsyncRoutes函数:
//定义一个函数:两个数组进行对比,对比出当前用户到底显示哪些异步路由
const computedAsyncRoutes = (asyncRoutes, routes) => {
//过滤出当前用户【超级管理|普通员工】需要展示的异步路由
return asyncRoutes.filter(item => {
//数组当中没有这个元素返回索引值-1,如果有这个元素返回的索引值一定不是-1
if (routes.indexOf(item.name) != -1) {
//递归:别忘记还有2、3、4、5、6级路由
if (item.children && item.children.length) {
item.children = computedAsyncRoutes(item.children, routes);
return true;
commit的时候对比好路由(需要深拷贝一下,不然对比后数据影响原数据)
<template>
<el-button type="primary" v-if="$store.state.user.buttons.indexOf('btn.Add1')!=-1">添加按钮1</el-button>
<el-button type="primary" v-if="$store.state.user.buttons.indexOf('btn.Add2')!=-1">添加按钮2</el-button>
</template>
第二种:基于菜单Menu的动态路由管理(推荐)
我这里是从0搭建的,很多细节需要自己处理,看起来比上面的方法麻烦其实不是这样的,上面是使用vue-admin很多细节作者已经处理好了,我这里需要自己处理,也更好的理解各种细节问题。
大致流程:(Vue3+TS+pinia实现)
这里的后台和上面的返回格式不一样,问题也不大。首页还是拿到token,用token拿用户信息,用户信息中有用户id,那个用户id去后台拿菜单信息。
然后进行路由对比,对比好就动态注册路由,要点击登录前就要计算好路由,也就是说push到首页就要算好路由,所有在login中actions进行对比,但是这个逻辑比较多,为了方便管理对比路由函数写在utils
在utils中:
这里用了两个for循环因为这里明确知道两次目录,要是children两层以上可以用递归
但是目前有一个问题就是,我注册权限路由是pinia的actions在点击登录按钮的回调进行注册的,现在当我刷新的时候这些路由就访问不到了,只能访问不用权限的路由,为什么会这样?
因为刷新不会重新加载pinia的actions的登录的回调,只有点击登录才会执行,解决办法就是刷新让这个回调重新执行一遍。具体实现如下:
在actions在定一个函数
第一种:基于角色Role的动态路由管理。登录:登录验证通过之后后台会返回一个token给前端,前端会保存在vuex和本地(防止刷新丢失登录状态),然后拿token去后台请求一个userInfo的接口获取用户信息(用户名,权限信息等等)权限验证:通过token获取用户role信息,然后根据用户role算出对应应有权限信息的路由,最后用router.addRotes动态挂载计算出的路由。
1.用户填写完账号和密码后向服务端验证是否正确,验证通过之后,服务端会返回一个token。
2.拿到token之后将这个token存起来,保证刷新页面后能记住用户登录状态,根据token去调用userInfo的接口来获取用户的详细信息(如用户权限,用户名等等信息)。
3.权限验证:通过token获取用户对应的权限,将请求的权限数组和用户信息存储到vuex中 ,动态根据用户的权限通过处理得到其对应有权限的路由,通过 router.addRoutes 动态添加这些路由。
一、登录:
登录成功后
一个系统包含众多模块,要求能够通过权限管理,控制不同用户对模块的访问权限,而且需要控制到对某个模块的某个操作(增删改查)的级别。一般情况下,通过角色对用户进行统一授权,在某些特殊情况下,能够单独对用户进行授权。
一、给用户分配角色。涉及到的模块有:
角色和用户的关系:以用户为主来进行设计符合客户的使用习惯,即将多个角色授予某个用户,也就是用户拥有多个
场景:不同的用户具有不同的权限,如只有vip用户可以享受高速下载服务,只有svip用户才可以享受极速下载服务。
思路:为用户添加角色,通过为角色添加权限从而达到权限控制的目的。
数据表构建
代码实现
model模型类:
from datetime import datetime
from django.db import models
from django.contrib.auth.models import AbstractUser
class UserProfile(Abstract
权限是用户可以访问的资源,包括页面权限、操作权限、数据权限
页面权限:即用户登录系统可以看到的页面,由菜单控制,菜单包括 一级菜单和二级菜单,只要用户有一级和二级菜单的权限,那么用户就可以访问页面;
操作权限:即页面的功能按钮,包括查看、新增、修改、删除、审核等。有的系统要求“可见即可操作“,意思是如果页面上能够看到操作按钮,那么用户就可以操作,要实现此需求,这里就需要前端来配合,前端开发把用户的权限信息缓存,在页面判断用户是否包含此权限,如果有,就显示该按钮,如...
用户权限管理的实现
在项目的开发中,常为不同的用户设置不同的角色,以使得不同的用户拥有不同的功能,例如:
1、给张三赋予“人力资源经理”角色,“人力资源经理”具有“查询员工”、“添加员工”、“修改员工”和“删除员工”权限。此时张三能够进入系统,则可以进行这些操作;
2、去掉李四的“人力资源经理”角色,此时李四就不能够进入系统进行这些操作了。
用户权限管理的
Spark中的两种核心shuffle分别是:
1. Hash Shuffle:基于哈希算法进行的洗牌,将数据按照key的哈希值分发到不同的节点。这种方式可以实现数据的随机性,但是在处理大规模数据时会造成大量内存开销。
2. Sort Shuffle:基于排序算法进行的洗牌,将数据进行排序后再进行分发。这种方式可以保证数据的有序性,并且相较于Hash Shuffle来说,内存开销较小。但是在处理数据的时候需要进行排序操作,所以比Hash Shuffle要慢一些。