前后端分离学习笔记 --[权限分配案例]

Posted 小智RE0

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了前后端分离学习笔记 --[权限分配案例]相关的知识,希望对你有一定的参考价值。

权限分配这块,其实在之前学习spring时,就已经作为案例练习过了;
不过当时没有整理;最近学习springboot和vue部分这块儿也是可以搭建这个案例

根据权限类型为不同的管理员生成不同的操作菜单

不同的管理员登录到系统后台后,仅能看到自己负责的操作管理菜单,这样的话,简化了管理员的操作,

就在上一篇笔记末尾整合的登录案例上进行------>登录模块


在登录时,会根据账号和密码查询出管理员的信息;查询到信息后;
会将该管理员的Id,账户名,以及管理员类型type存储到token令牌中;
特殊处理后会连同响应信息送到浏览器客户端;


在上篇笔记中已经完成;
用户在第一次登录成功后,会把token令牌的信息以及自己的账号名存储到浏览器的session中’;

注意这个axios请求拦截,他会把浏览器发往服务器的请求拦截,然后为它们的请求头添加 token令牌信息;

管理员表
管理员的列type :默认为1 ; 0表示超级管理员;1表示普通管理员

角色表

管理员与角色关系表

菜单表
菜单类型:type : 默认为1 ; 0表示系统菜单 ; 1表示业务菜单

菜单角色关系表

前端页面之main.vue组件;

管理员成功登录后就会路由跳转到这个main路径的页面;

<template>
	<el-container style="height:100%">
		<!-- 上面的一整条导航栏 -->
	  <el-header style="text-align: right; font-size: 12px">
	   <el-dropdown>
	          <i class="el-icon-setting" style="margin-right: 15px"></i>
			  <!-- 右上角个人中心的几个选项-->
	          <el-dropdown-menu slot="dropdown">
	            <!-- <el-dropdown-item>修改密码</el-dropdown-item>
	            <el-dropdown-item>上传头像</el-dropdown-item> -->
	            <el-dropdown-item @click.native="exit()">退出登录</el-dropdown-item>
	          </el-dropdown-menu>
	        </el-dropdown>
	        <span>account</span>
	 </el-header>
	  <el-container>
		<!-- 左侧的侧边栏 -->
	    <el-aside width="200px">
			<!-- :default-openeds菜单的默认打开数;这里需要加入路由router -->
			 <el-menu :default-openeds="['1', '0']" router="">
			      <el-submenu index="1">
			        <template slot="title"><i class="el-icon-setting"></i>操作</template>
			        <el-menu-item-group>
					<!-- 这里的文字会绑定上菜单的路径地址,点击即可跳转 -->	
			        <el-menu-item v-bind:index="menu.url" v-for="(menu,index) in menuList" :key="index">menu.name</el-menu-item>
			        </el-menu-item-group>
			      </el-submenu>
			    </el-menu>
		</el-aside>
		
	    <el-container>
			<!-- 中间的主信息页面 -->
	      <el-main>
			  <!-- 这里会显示路由跳转过来的视图-->
			  <router-view></router-view>
		  </el-main>
		  <!-- 底部栏的话本次案例练习暂时不用-->
	      <!-- <el-footer>Footer</el-footer> -->
	    </el-container>
	  </el-container>
	</el-container>
</template>

<script>
	export default
		data:function()
			return
				//账号名;
				account:"",
				//菜单列表;
				menuList:[],
			
		,
		methods:
			//安全退出
			exit()
			    //先给个提示信息;
				 this.$confirm('您确定退出吗?', '提示', 
				          confirmButtonText: '确定',
				          cancelButtonText: '取消',
				          type: 'warning'
				        ).then(() => 
				        //这里不需要向后端发送请求,清除前端的session即可;
				          window.sessionStorage.clear();
				          //跳转到登录页面;
				          this.$router.push("/login");
				        )
				
		,
		//加载页面时就触发
		created()
			//从session中取到管理员的账户名; 赋值给数据域的定义模型变量 account
			this.account = window.sessionStorage.getItem("account");
			//注意this是vue对象;要是直接在请求里面写this的话表示的是axios对象;
			var _this = this;
			//发出请求,查询该管理员负责的菜单;注意不用带参数,请求头中的token里面就有用户的信息;
			this.$http.get("login/findMenuList").then(function(resp)
				console.log(resp);
				_this.menuList = resp.data.data;
			);
		
	
</script>

<style>
	.el-header 
	    background-color: #00FFFF;
	    color: #333;
	    text-align: center;
	    line-height: 60px;
	  
	  
	  .el-aside 
	    background-color: #67C23A;
	    color: #333;
	  
	  
	  .el-main 
	    background-color: #E9EEF3;
	    color: #333;
	  
</style>

管理员类

/**
 * @author by 信计1801班 李智青(小智RE0)
 * @date 2021-12-29 14:49
 */
@Data
@Component
public class Admin 
    private Integer id;
    private String account;
    private String password;
    private String token;
    private String sex;
    private String phone;
    //角色数组;
    private Integer[] roleId;
    //旧的,新的文件名;
    private String oldFileName;
    private String newFileName;
    //权限类型;0超管1:普通管理员
    private Integer type;
    //关联了多个角色;
    private List<Role> roleList;
    private Date operTime;

角色类

/**
 * @author by 信计1801班 李智青(小智RE0)
 * @date 2021-12-29 15:44
 */
@Component
@Data
public class Role 
    //角色ID,姓名,描述;操作人,操作时间;
    private Integer id;
    private String name;
    private String roleDesc;
    private Admin admin;
    private Date  operTime;
    //关联多个菜单;
    private List<Menu> menuList;
    //菜单栏的Id数组;
    private Integer[] menuId;

菜单类

/**
 * @author by 信计1801班 李智青(小智RE0)
 * @date 2021-12-29 15:43
 */
@Component
@Data
public class Menu 
    //菜单ID,名称,链接;
    private Integer id;
    private String name;
    private String url;
    //类型;0系统菜单1业务菜单;
    private Integer type;

登录的映射文件LoginMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--注意 这里对应空间为持久层映射接口-->
<mapper namespace="com.xiaozhi.backserver.startspringboot.dao.LoginDao">

    <select id="loginUser" resultType="admin">
        select  id,account,type from t_admin where account=#account and password=#password
    </select>

    <!--根据权限的不同来获取菜单 类型type:0表示超级管理员负责的系统菜单,1:表示普通管理员负责的业务菜单-->
    <select id="findMenuList" resultType="menu">
        <choose>
            <when test="type==0">
                select name, url from t_menu where type =0
            </when>
            <otherwise>
                SELECT
                DISTINCT
                m.name,m.url
                FROM t_admin_role ar LEFT JOIN t_role_menu rm ON  rm.role_id=ar.role_id
                LEFT JOIN t_menu m ON m.id = rm.menu_id
                WHERE ar.admin_id =#id
            </otherwise>
        </choose>
    </select>
</mapper>

登录处理的持久层dao
LoginDao

/**
 * @author by @CSDN 小智RE0
 * @date 2021-12-28 15:55
 */
@Repository
public interface LoginDao 

    //根据账号和密码验证用户;
    Admin loginUser(Admin admin);

    //根据Id查到对应的菜单;
    List<Menu> findMenuList(Admin admin);

登录处理的服务层service
LoginService

在管理员登录后,进入main主页面时,加载时就发出请求,虽然没有传递参数;
但是在请求头中的token令牌已经存储了该管理员的个人信息,
那么就会通过JWT工具类的方法getTokenInfo(token),将token中的信息进行解析,得到查询条件需要的信息(管理员的Id和类型type);
注意在当时对管理员的信息存储到token时,是使用了键值对的形式存入的;
那么这里解析后,也就需要用对应的键获取到信息.

@Transactional
@Service
public class LoginService 
    @Autowired
    LoginDao loginDao;

    //验证用户登录
    public Admin loginUser(Admin admin)
        return loginDao.loginUser(admin);
    

    //根据管理员的Id查询到对应的菜单;
    public List<Menu> findMenuList(String token) 
        //由token中获取Id和type;
        DecodedJWT info = JWTUtil.getTokenInfo(token);
        Integer id = info.getClaim("id").asInt();
        Integer type = info.getClaim("type").asInt();

        Admin admin = new Admin();
        admin.setId(id);
        admin.setType(type);
        return loginDao.findMenuList(admin);
    

登录处理的控制层controller方法
LoginController

/**
 * @author by @CSDN 小智RE0
 * @date 2021-12-27
 *
 */
@RestController
@RequestMapping(value = "/api/login")
public class LoginController 


    CommonResult commonResult;

    @Autowired
    LoginService loginService;


    //跨域接收;
    //@CrossOrigin("http://localhost:8080/")
    @RequestMapping(value = "/login")
    public CommonResult login(@RequestBody Admin admin)
        try
            System.out.println(admin);

            Admin admin1 = loginService.loginUser(admin);
            if(admin1!=null)
                String token = JWTUtil.token(admin1.getId(), admin1.getAccount(),admin1.getType());
                admin1.setToken(token);

                commonResult = new CommonResult(200,"正确",admin1);
            else
                commonResult = new CommonResult(201,"账号或密码错误",null);
            
        catch (Exception e)
            e.printStackTrace();
            commonResult = new CommonResult(500,"服务器错误",null);
        
        return commonResult;
    


    //查询出该角色对应的菜单;
    @GetMapping("/findMenuList")
    @ResponseBody
    public CommonResult findMenuList(@RequestHeader("token") String token)

        try
            List<Menu> menuList = loginService.findMenuList(token);
            if(!menuList.isEmpty())
                commonResult = new CommonResult(200,"查询菜单成功",menuList);
            else 
                commonResult = new CommonResult(201,"该角色暂无菜单分配",null);
            
        catch (Exception e)
            e.printStackTrace();
            commonResult = new CommonResult(500,"查询菜单成功",null);
        
        return commonResult;
    

启动前端和后端服务;

登录admin;超级管理员身份; 菜单就是角色管理和管理员管理

现在这位普通管理员登录后就看到他负责的管理菜单了

若管理员没有负责的菜单,他登录进去后就不会看到操作菜单部分

以上是关于前后端分离学习笔记 --[权限分配案例]的主要内容,如果未能解决你的问题,请参考以下文章

Python全栈100天学习笔记Day48 前后端分离开发入门

Python全栈100天学习笔记Day48 前后端分离开发入门

前后端分离学习笔记 ---[路由嵌套, 查询表单显示]

前后端分离学习笔记 --[管理员权限分配操作菜单案例]

RuoYi 若依后台管理系统-学习笔记-前后端分离项目中下拉框验证失效

RuoYi 若依后台管理系统-学习笔记-前后端分离项目中下拉框验证失效