前言
在最近的项目中,有对于不同用户分配不同权限的需求,以前写的时候知识跟着用,这次按照 登录-刷新-验证 打算自己去看一遍(使用element-ui)
话不多说,本文我分为两个角色去瞅一眼
管理员
登录
在login.vue页面
handleLogin() {
this.$refs.loginForm.validate((valid) => {
console.log(valid)
const user = {
username: this.loginForm.username,
password: this.loginForm.password,
rememberMe: this.loginForm.rememberMe,
code: this.loginForm.code,
uuid: this.loginForm.uuid
}
if (user.password !== this.cookiePass) {
user.password = encrypt(user.password)
}
if (valid) {
this.loading = true
if (user.rememberMe) {
Cookies.set('username', user.username, {
expires: Config.passCookieExpires
})
Cookies.set('password', user.password, {
expires: Config.passCookieExpires
})
Cookies.set('rememberMe', user.rememberMe, {
expires: Config.passCookieExpires
})
} else {
Cookies.remove('username')
Cookies.remove('password')
Cookies.remove('rememberMe')
}
// 发送,action,验证登录
this.$store
.dispatch('Login', user)
.then(() => {
this.loading = false
this.$router.push({ path: this.redirect || '/' })
})
.catch(() => {
this.loading = false
this.getCode()
})
} else {
console.log('error submit!!')
// return false
}
})
}
我们可以在登录页面看到,首先验证了用户填写的表单,然后发送 action 去请求登录接口
可以预见,eladmin是要把登录接口返回的信息存在 vuex 中,那么登录接口返回的东西肯定包含了很多用户的个人信息。
vuex模块化
框架划分了处理各个不同业务的js文件
在store/modules/user.js中
// 登录
action: {
Login({ dispatch, commit }, userInfo) {
return new Promise((resolve, reject) => {
login(userInfo.username, userInfo.password, userInfo.code, userInfo.uuid).then(res => {
// 在这里调用存储用户信息方法
setUserInfo(res.data.user, commit)
resolve()
}).catch(error => {
reject(error)
})
})
}
}
export const setUserInfo = (res, commit) => {
// 如果没有任何权限,则赋予一个默认的权限,避免请求死循环
if (res.roles.length === 0) {
commit('SET_ROLES', ['ROLE_SYSTEM_DEFAULT'])
} else {
commit('SET_ROLES', res.roles)
}
commit('SET_USER', res.user)
}
mutations: {
SET_USER: (state, user) => {
state.user = user
},
SET_ROLES: (state, roles) => {
state.roles = roles
}
},
state: {
token: getToken(),
user: {},
roles: [],
// 第一次加载菜单时用到
loadMenus: false,
// 消息列表
notices: []
}
在这里我们可以看到,在请求登录接口获得返回信息后,将用户信息通过提 mutations
存放在 state 中。
这是登录接口返回的用户信息,里面 role 字段里可以看到它是一个数组。
验权
v-permission 是eladmin的一个自定义指令
到处都可以看到操作表单时候的v-permission字段
<el-table-column
v-permission="['admin', 'user:edit', 'user:del']"
label="操作"
align="center"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
:permission="permission"
:disabled-dle="scope.row.id === user.id"
>
</udOperation>
</template>
</el-table-column>
与之对应的是传给组件的 permission
它是在 data 中定义的权限列表
permission: {
add: ['admin', 'user:add'],
edit: ['admin', 'user:edit'],
del: ['admin', 'user:del']
}
再来看 src/components/Permission.js文件
inserted(el, binding, vnode) {
// 解构赋值拿到v-permission绑定的值
const { value } = binding
// 获取gatters里面的roles(user下的roles)
const roles = store.getters && store.getters.roles
if (value && value instanceof Array && value.length > 0) {
const permissionRoles = value
// 判断roles里面是否含有v-permission绑定的值
const hasPermission = roles.some(role => {
return permissionRoles.includes(role)
})
if (!hasPermission) {
el.parentNode && el.parentNode.removeChild(el)
}
} else {
throw new Error(`使用方式: v-permission="['admin','editor']"`)
}
}
v-permission做了什么事情
对比于下方 v-permission 和 自定义的permission。我们来看一下这个自定义指令做了什么事情
<el-table-column
v-permission="['admin', 'user:edit', 'user:del']"
label="操作"
align="center"
fixed="right"
>
<template slot-scope="scope">
<udOperation
:data="scope.row"
:permission="permission"
>
</udOperation>
</template>
</el-table-column>
permission: {
add: ['admin', 'user:add'],
edit: ['admin', 'user:edit'],
del: ['admin', 'user:del']
}
在这里,我打印 v-permission 得到的是(对应Permission.js文件中接收的 binding)
再打印看看用户的 roles(对应存在vuex里的 user.roles)
我们发现,当登录管理员的时候,打印出来的是上图。
结论
所以如果要让管理员拥有对某个表格的增删改权限
只需要在表格 v-permission 列表中添加 ‘admin’ 字段就可以了。
用户
用户角色
对于普通用户,我们打印他的 user.role 如下图
在普通用户登录状态下,数据库中存储了当前用户可以操作按钮的全部记录。
用户结论
当检查用户的权限能否操作当前按钮,会获取当前用户所有的按钮权限,然后跟当前绑定的 v-permission 的值比对。当匹配到了,就代表用户可以操作此权限。
所以要给用户分配某个按钮权限:
- 需要在 v-permission 中写上当前权限标识。
- 然后在菜单页面,添加按钮,然后写上相应的权限标识。
- 再在角色管理页面给相应用户分配这个权限。