vue+springboot+shiro实现权限系统的思路

参考项目

代码实现思路

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’]

发布了437 篇原创文章 · 获赞 82 · 访问量 18万+

猜你喜欢

转载自blog.csdn.net/qq_41063141/article/details/103713456