09 路由守卫对url鉴权

登陆后,从后台加载出当前登录用户的信息

1 登录信息实体类

package com.grm.entity;

import java.io.Serializable;
import java.util.List;

/**
 * 登录用户信息(用户名+头像,菜单列表)
 *
 * @author gaorimao
 * @date 2022/02/10
 */
public class LoginUserInfo implements Serializable {
    /**
     * 用户名
     */
    private String username;
    /**
     * 头像
     */
    private String avatar;
    /**
     * 系统菜单
     */
    private List<SysMenu> sysMenus;
    /**
     * 用户所拥有的url权限、按钮权限
     */
    private List<String> perms;

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public List<SysMenu> getSysMenus() {
        return sysMenus;
    }

    public void setSysMenus(List<SysMenu> sysMenus) {
        this.sysMenus = sysMenus;
    }

    public List<String> getPerms() {
        return perms;
    }

    public void setPerms(List<String> perms) {
        this.perms = perms;
    }
}

2 首页加载Controller

package com.grm.controller;

import com.grm.common.Result;
import com.grm.entity.LoginUserInfo;
import com.grm.service.IndexService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 首页控制器,加载用户信息和所拥有的菜单列表
 *
 * @author gaorimao
 * @date 2022/02/10
 */
@Slf4j
@RestController
public class IndexController {
    @Autowired
    private IndexService indexService;

    @GetMapping("/getLoginUserInfo")
    public Result getLoginUserInfo() {
        LoginUserInfo loginUserInfo = indexService.getLoginUserInfo();
        return Result.success("加载登录用户信息成功!", loginUserInfo);
    }
}

3 IndexSerivce

package com.grm.service;

import com.grm.entity.LoginUserInfo;
import com.grm.entity.SysMenu;
import com.grm.security.details.LoginUser;
import com.grm.util.RedisUtil;
import com.grm.util.SecurityUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * 首页逻辑(获取登录用户信息和用户所拥有的菜单信息)
 *
 * @author gaorimao
 * @date 2022/02/11
 */
@Service
public class IndexService {
    @Autowired
    private RedisUtil redisUtil;
    @Autowired
    private SecurityUtils securityUtils;
    @Autowired
    private SysMenuService sysMenuService;

    public LoginUserInfo getLoginUserInfo() {
        // 1. 获取当前登录用户
        LoginUser loginUser = securityUtils.getLoginUser();

        LoginUserInfo loginUserInfo;
        // 从缓存中获取当前登录用户信息
        Object loginUserInfoObj = redisUtil.get("LoginUserInfo:" + loginUser.getUsername());
        if (!ObjectUtils.isEmpty(loginUserInfoObj)) {
            // 从缓存中拿
            loginUserInfo = (LoginUserInfo) loginUserInfoObj;
        } else {
            // 从DB中拿
            loginUserInfo = queryLoginUserInfoByDb(loginUser);
            // 存入缓存一份
            redisUtil.set("LoginUserInfo:" + loginUser.getUsername(), loginUserInfo, 60 * 60 * 24 * 7);
        }
        return loginUserInfo;
    }

    /**
     * 从数据库查询登录用户信息
     *
     * @param loginUser 登录用户
     * @return {@link LoginUserInfo}
     */
    private LoginUserInfo queryLoginUserInfoByDb(LoginUser loginUser) {
        // 1.获取用户头像
        String avatar = loginUser.getAvatar();
        // 2.获取用户菜单
        List<SysMenu> sysMenus = getSysMenusByUserId(loginUser.getUserId());
        List<SysMenu> sysMenuTree = sysMenuService.buildTree(sysMenus);
        // 3.获取用户权限
        List<String> perms = getPermsByUserId(sysMenus);
        LoginUserInfo loginUserInfo = new LoginUserInfo();
        loginUserInfo.setUsername(loginUser.getUsername());
        loginUserInfo.setAvatar(avatar);
        loginUserInfo.setSysMenus(sysMenuTree);
        loginUserInfo.setPerms(perms);
        return loginUserInfo;
    }

    /**
     * 根据用户id获取用户所具有的权限
     *
     * @param sysMenus 用户所拥有的菜单
     * @return {@link List}<{@link String}>
     */
    private List<String> getPermsByUserId(List<SysMenu> sysMenus) {
        List<String> perms = new ArrayList<>();
        if(ObjectUtils.isNotEmpty(sysMenus)){
            for (SysMenu sysMenu : sysMenus){
                if(ObjectUtils.isNotEmpty(sysMenu.getPath())){
                    perms.add(sysMenu.getPath());
                }
                if(ObjectUtils.isNotEmpty(sysMenu.getPerms())){
                    perms.add(sysMenu.getPerms());
                }
            }
        }
        return perms;
    }

    /**
     * 通过用户id获取系统菜单
     *
     * @param userId 登录用户id
     * @return {@link List}<{@link SysMenu}>
     */
    private List<SysMenu> getSysMenusByUserId(Long userId){
        List<SysMenu> sysMenus;
        if (securityUtils.isAdmin(userId)) {
            // 查所有目录和菜单
            sysMenus = sysMenuService.queryMenusByUserId(null);
        } else {
            sysMenus = sysMenuService.queryMenusByUserId(userId);
        }
        // 转换成树结构
        return sysMenus;
    }
}

4 接口测试

 返回的json

{
	"code": 200,
	"message": "加载登录用户信息成功!",
	"data": {
		"username": "admin",
		"avatar": "https://img2.baidu.com/it/u=1437480680,2169625508&fm=253&fmt=auto&app=138&f=JPEG?w=360&h=360",
		"sysMenus": [{
			"id": 1,
			"parentId": 0,
			"label": "系统管理",
			"path": "",
			"perms": "sys:manage",
			"type": 0,
			"icon": "el-icon-setting",
			"orderNum": 0,
			"created": "2022-02-02 23:41:46",
			"updated": "2022-02-02 23:41:48",
			"children": [{
				"id": 2,
				"parentId": 1,
				"label": "用户管理",
				"path": "/sys/user",
				"perms": "sys:user:list",
				"type": 1,
				"icon": "el-icon-user",
				"orderNum": 0,
				"created": "2022-02-02 23:43:34",
				"updated": "2022-02-02 23:43:35",
				"children": []
			}, {
				"id": 3,
				"parentId": 1,
				"label": "角色管理",
				"path": "/sys/role",
				"perms": "sys:role:list",
				"type": 1,
				"icon": "el-icon-user-solid",
				"orderNum": 1,
				"created": "2022-02-02 23:44:34",
				"updated": "2022-02-02 23:44:36",
				"children": []
			}, {
				"id": 4,
				"parentId": 1,
				"label": "菜单管理",
				"path": "/sys/menu",
				"perms": "sys:menu:list",
				"type": 1,
				"icon": "el-icon-menu",
				"orderNum": 2,
				"created": "2022-02-02 23:45:13",
				"updated": "2022-02-02 23:45:15",
				"children": []
			}]
		}, {
			"id": 5,
			"parentId": 0,
			"label": "OA管理",
			"path": "",
			"perms": "oa:manage",
			"type": 0,
			"icon": "el-icon-thumb",
			"orderNum": 1,
			"created": "2022-02-05 03:21:08",
			"updated": "2022-02-05 03:21:09",
			"children": [{
				"id": 6,
				"parentId": 5,
				"label": "群组管理",
				"path": "/oa/group",
				"perms": "oa:group:list",
				"type": 1,
				"icon": "el-icon-chat-round",
				"orderNum": 0,
				"created": "2022-02-05 03:22:42",
				"updated": "2022-02-05 03:22:45",
				"children": []
			}, {
				"id": 7,
				"parentId": 5,
				"label": "我的申请",
				"path": "/oa/apply",
				"perms": "oa:apply:list",
				"type": 1,
				"icon": "el-icon-stopwatch",
				"orderNum": 1,
				"created": "2022-02-05 03:23:33",
				"updated": "2022-02-05 03:23:34",
				"children": []
			}, {
				"id": 8,
				"parentId": 5,
				"label": "我的审批",
				"path": "/oa/approve",
				"perms": "oa:approve:list",
				"type": 1,
				"icon": "el-icon-key",
				"orderNum": 2,
				"created": "2022-02-05 03:24:42",
				"updated": "2022-02-05 03:24:44",
				"children": []
			}]
		}],
		"perms": ["sys:manage", "oa:manage", "/sys/user", "sys:user:list", "/sys/role", "sys:role:list", "/sys/menu", "sys:menu:list", "/oa/group", "oa:group:list", "/oa/apply", "oa:apply:list", "/oa/approve", "oa:approve:list"]
	}
}

5 路由权限拦截(此处只能拦截目录和菜单,拦截不了按钮)

在router/index.js中,加入elementui消息提示

import { Message } from 'element-ui';

加入路由拦截配置

登陆成功时,需要存储后台返回的token

localStorage.setItem('token')

首页加载时,需要存储后台返回的perms

localStorage.setItem('perms')

router.beforeEach((to, from, next) => {
  if (to.path != '/' && to.path != '/login' && to.path != '/logout' && to.path != '/noPermission') {
    // 检测是否登录
    if (localStorage.getItem('token') == '') {
      Message.error("用户未登录!");
      next('/login');
    } else {
      // 1. index和home不需要鉴权
      if (to.path == "/index" || to.path == "/home") {
        next();
      } else {
        var perms = localStorage.getItem('perms')
        if (perms == null) {
          // 鉴权未通过
          Message.error("鉴权未通过")
          next("/noPermission")
        } else {
          // 鉴权通过
          if (perms.indexOf(to.path) != -1) {
            next()
          } else {
            // 鉴权未通过
            Message.error("鉴权未通过")
            next("/noPermission")
          }
        }
      }
    }
  } else {
    next()
  }
})

编写鉴权401错误页面

<template>
  <div class="noPermission">
    <div class="errorContent">
      <img
        :src="errGif"
        width="313px"
        height="428px"
        alt="Girl has dropped her ice cream."
      />
      <h2 style="text-align: center">您没有访问权限!</h2>
    </div>
  </div>
</template>

<script>
import errGif from "@/assets/401.gif";

export default {
  name: "NoPermission",
  data() {
    return {
      errGif: errGif + "?" + +new Date(),
    };
  },
};
</script>

<style scoped>
.errorContent {
  position: absolute;
  left: 52%;
  top: 48%;
  transform: translate(-52%, -48%);
}
</style>

使用user用户,登录,直接通过url强制访问/sys/menu,路由守卫已经起作用了

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值