代码实现思路
main.js
//全局的常量
Vue.prototype.hasPerm = hasPermission
hasPermission.js
import store from '../store'
export function hasPermission(permission) {
let myPermissions = store.getters.permissions;
return myPermissions.indexOf(permission) > -1;
}
user.js
//store.getters.permissions;
const user = {
state: {
nickname: "",
userId: "",
avatar: 'https://www.gravatar.com/avatar/6560ed55e62396e40b34aac1e5041028',
role: '',
menus: [],
permissions: [],
},
mutations: {
SET_USER: (state, userInfo) => {
state.nickname = userInfo.nickname;
state.userId = userInfo.userId;
state.role = userInfo.roleName;
state.menus = userInfo.menuList;
state.permissions = userInfo.permissionList;
},
// 获取用户信息
GetInfo({commit, state}) {
return new Promise((resolve, reject) => {
api({
url: '/login/getInfo',
method: 'post'
}).then(data => {
//储存用户信息
commit('SET_USER', data.userPermission); //用户登录后,后端返回所有的权限给前端
//cookie保存登录状态,仅靠vuex保存的话,页面刷新就会丢失登录状态
setToken();
//生成路由
let userPermission = data.userPermission ;
store.dispatch('GenerateRoutes', userPermission).then(() => {
//前端将权限注入到路由
//生成该用户的新路由json操作完毕之后,调用vue-router的动态新增路由方法,将新路由添加
router.addRoutes(store.getters.addRouters)
})
resolve(data)
}).catch(error => {
reject(error)
})
})
},
// 登出
LogOut({commit}) {
return new Promise((resolve) => {
api({
url: "login/logout",
method: "post"
}).then(data => {
commit('RESET_USER')
//登出就是移除token
removeToken()
resolve(data);
}).catch(() => {
commit('RESET_USER')
removeToken()
})
})
},
用户一登录,后端就把所有的权限给前端。前端存入入到全局的store.user里面。权限格式为:
["article:add"," user:add","role:update"]
//验证方式:
<el-table-column align="center" label="管理" width="200" v-if="hasPerm('article:update')">
<template slot-scope="scope">
<el-button type="primary" icon="edit" @click="showUpdate(scope.$index)">修改</el-button>
</template>
</el-table-column>
//如果有权限,改按钮就会显示,没有权限,改按钮就会隐藏
//前端处理逻辑
<div slot="footer" class="dialog-footer">
<el-button @click="dialogFormVisible = false">取 消</el-button>
<el-button v-if="dialogStatus=='create'" type="success" @click="createArticle">创 建</el-button>
<el-button type="primary" v-else @click="updateArticle">修 改</el-button>
</div>
updateArticle() {
//修改文章
this.api({
url: "/article/updateArticle",
method: "post",
data: this.tempArticle
}).then(() => {
this.getList();
this.dialogFormVisible = false
})
},
后端的shiro里面的userRealm
protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
Session session = SecurityUtils.getSubject().getSession();
//查询用户的权限
JSONObject permission = (JSONObject) session.getAttribute(Constants.SESSION_USER_PERMISSION);
logger.info("permission的值为:" + permission);
logger.info("本用户权限为:" + permission.get("permissionList"));
//为当前用户设置角色和权限----也是在登录时就查询权限,交给全局的shiro的realm里面。这样用户过来,直接从realm里面查
SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
authorizationInfo.addStringPermissions((Collection<String>) permission.get("permissionList"));
return authorizationInfo;
}
shiro和springboot整合后的权限的检查的注解
package org.apache.shiro.authz.annotation;
@java.lang.annotation.Target({java.lang.annotation.ElementType.TYPE, java.lang.annotation.ElementType.METHOD})
@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME)
public @interface RequiresPermissions {
java.lang.String[] value();
org.apache.shiro.authz.annotation.Logical logical() default org.apache.shiro.authz.annotation.Logical.AND;
}
//后端逻辑
/**
* 新增文章
*/
@RequiresPermissions("article:add")
@PostMapping("/addArticle")
public JSONObject addArticle(@RequestBody JSONObject requestJson) {
CommonUtil.hasAllRequired(requestJson, "content");
return articleService.addArticle(requestJson);
}
/**
* 修改文章
*/
@RequiresPermissions("article:update")
@PostMapping("/updateArticle")
public JSONObject updateArticle(@RequestBody JSONObject requestJson) {
CommonUtil.hasAllRequired(requestJson, "id,content");
return articleService.updateArticle(requestJson);
}
整体实现思路及流程
用户先通过前台登录,此时后台会根据用户信息查出用户所有的权限并存入userRealm里面【这是全局—只有用户处于已登录状态。这个全局变量就一直有效】。后端还会在与权限有关的接口上都加上shrio的权限注解,已对请求做权限的拦截。【如:@RequiresPermissions(“article:update”)】。此时后端会把用户的所具有的所有权限都发给前端。前端同样也将权限存入到全局变量store里面【这是全局—只有用户处于已登录状态。这个全局变量就一直有效】.前端可通过如下方式进行权限控制【< div v-if=“hasPerm(‘article:add’)” > 添加< /div>】
比如现在是A用户登录得,那对A而言< div v-if=“hasPerm(‘article:add’)” > 添加< /div>可见
对B,C而言< div v-if=“hasPerm(‘article:add’)” > 添加< /div>不可见
比如hasPerm(‘xxxx’)
A用户的xxx是[‘article:add’,‘article:delete’,'article:‘list’]
B用户的xxx是[‘article:add’,‘article:list’]
C用户的xxx是[‘article:list’]