若依权限系统分析(前后端分离版)

news2024/11/15 11:41:53

若依权限系统分析

  • 一:故事背景
  • 二:具体权限控制
    • 2.1 页面权限控制
    • 2.2 页面元素权限控制
  • 三:实现前端鉴权
    • 3.1 封装js与权限交互
      • 3.1.1 uni-app自带uni-request与权限交互
    • 3.2 vux状态管理
      • 3.2.1 自定义状态
      • 3.2.2 在vuex的store配置内添加我们新增的状态管理
    • 3.3 全局路由守卫鉴权
  • 四:总结提升

一:故事背景

最近在研究权限系统。秉承着站在巨人的肩膀上的原则,去学习了若依的权限项目。这里选用的是前后端分离版。去研究了界面的控制和页面内元素的控制。查看了其具体的实现方法,将其总结到这里。

二:具体权限控制

若依权限控制主要分为两大部分,第一部分是页面的控制,第二部分是页面上具体元素的控制。
在这里插入图片描述

  1. 在若依的系统中,菜单管理内可以看到所有元素。元素分为两种。一种是页面,另外一种是元素是页面内的具体元素。
  2. 无论是哪种元素,我们都可以自定义对应的 权限标识,通过权限表示来表示用户有没有具体的权限。

2.1 页面权限控制

页面权限控制是通过动态路由的方式进行的配置,我们从前端到后端,整个流程看一下其实现动态路由的整个过程

  1. src目录下的permission文件,这里代码意思是VueRouter中的全局前置守卫,用于在路由切换前执行一些逻辑操作。
    首先判断用户已经登录,有对应的token,然后去拉取用户的信息,拉去完之后去触发 Vuex的GenerateRoutes方法,去后端拉取具体的路由信息
    在这里插入图片描述
  2. 上文所述的 Vuex的GenerateRoutes方法 定义在 src.store.modules.permission.js 文件内,注意和上面的文件区分,二者目录不同
    在这里插入图片描述
    这部分代码,去后端查询了用户具有的路由权限等信息,将生成的可访问的路由配置作为 Promise 的结果返回。
    返回之后,第一部分的代码将可访问的路由动态的配置到了 Vue Router 中。
  3. 下面是请求路由数据返回的数据结构
{
    "msg": "操作成功",
    "code": 200,
    "data": [
        {
            "name": "System",
            "path": "/system",
            "hidden": false,
            "redirect": "noRedirect",
            "component": "Layout",
            "alwaysShow": true,
            "meta": {
                "title": "系统管理",
                "icon": "system",
                "noCache": false,
                "link": null
            },
            "children": [
                {
                    "name": "User",
                    "path": "user",
                    "hidden": false,
                    "component": "system/user/index",
                    "meta": {
                        "title": "用户管理",
                        "icon": "user",
                        "noCache": false,
                        "link": null
                    }
                },
                {
                    "name": "Role",
                    "path": "role",
                    "hidden": false,
                    "component": "system/role/index",
                    "meta": {
                        "title": "角色管理",
                        "icon": "peoples",
                        "noCache": false,
                        "link": null
                    }
                },
                {
                    "name": "Menu",
                    "path": "menu",
                    "hidden": false,
                    "component": "system/menu/index",
                    "meta": {
                        "title": "菜单管理",
                        "icon": "tree-table",
                        "noCache": false,
                        "link": null
                    }
                },
                {
                    "name": "Dept",
                    "path": "dept",
                    "hidden": false,
                    "component": "system/dept/index",
                    "meta": {
                        "title": "部门管理",
                        "icon": "tree",
                        "noCache": false,
                        "link": null
                    }
                },
                {
                    "name": "Post",
                    "path": "post",
                    "hidden": false,
                    "component": "system/post/index",
                    "meta": {
                        "title": "岗位管理",
                        "icon": "post",
                        "noCache": false,
                        "link": null
                    }
                },
                {
                    "name": "Dict",
                    "path": "dict",
                    "hidden": false,
                    "component": "system/dict/index",
                    "meta": {
                        "title": "字典管理",
                        "icon": "dict",
                        "noCache": false,
                        "link": null
                    }
                }
            ]
        }
    ]
}

2.2 页面元素权限控制

  1. 页面元素控制,通过权限id进行的相应控制,在若依的权限系统中,定义了v-hasPermi 和 v-hasRole 两个Vue指令。分别用来控制操作权限和角色权限处理。
    在这里插入图片描述

  2. 在用户登录的时候,会调用getInfo接口,获取用户对应的权限id的字段,并且将其存储到vuex的状态中,可以在其他的组件中通过Vuex的getters获取具体的信息
    在这里插入图片描述
    getUserInfo获得的具体的用户权限信息
    在这里插入图片描述

  3. 页面鉴权的时候直接通过 v-hasPermi 来进行对应的鉴权,如果该用户返回了对应的权限id,该用户对此控件就有具体的操作权限
    在这里插入图片描述

三:实现前端鉴权

基于若依,我自己封装了一个前端鉴权方式。通过调用若依权限接口,二次开发接口的方式,实现了路由鉴权
此实现主要涉及到以下几方面:
1.封装js与权限系统交互。
2.利用vuex实现状态管理,管理用户可访问的路由路径
3.全局路由守卫,实现鉴权

3.1 封装js与权限交互

我这里封装了两种js与权限系统交互,一种是利用axios、一种是利用uni-app框架的uni-request进行访问。

3.1.1 uni-app自带uni-request与权限交互

//使用uni.request方式发送http请求
//登陆获取token
const  AUTH_LOGIN_URL= "http://localhost:8000/auth/login"
//获取用户权限
const AUTH_USERINFO_URL="http://localhost:8000/auth/getResource"

//返回token值等数据
const state = {
    //token值
    token:'',
    //路由
    routes:[],
    //权限id
    permissions:[]

}

//登陆获取token,以及用户权限
export function getAuth(data) {
    return new Promise((resolve, reject) => {
    
      sendRequest(AUTH_LOGIN_URL, 'post', data)
        .then(response => {
          // 请求token返回值
          console.log("response",response);
          state.token = response.data.token;
          console.log("token",data);
          getUserInfo(state.token).then(userRespone=>{
            state.permissions = userRespone.data.permissions;
            state.routes = userRespone.data.component;
            resolve(state)
          })

        })
        .catch(error => {
          // 请求发生错误,进行错误处理
          console.error(error);
          reject(error); // 将错误传递给调用者
        });
    });
  }

  //通过token获取用户权限
 function  getUserInfo(token){
    return new Promise((resolve, reject) => {
        sendRequest(AUTH_USERINFO_URL, 'get', null,token)
          .then(response => {
            // 请求token返回值
            console.log("请求路由权限成功",response)
            resolve(response); // 将结果传递给调用者
          })
          .catch(error => {
            // 请求发生错误,进行错误处理
            console.error("发生错误",error);
            reject(error); // 将错误传递给调用者
          });
      });
}

  function sendRequest(url, method, data, token) {

    return new Promise(function(resolve, reject){
         uni.request({
            url: url,
            method: method,
            data: data,
            header: {
              'Authorization': 'Bearer ' + token // 设置 Authorization 头部
            }
          }).then(responses=>{
          // 异常
            if (responses[0]) {
                reject({message : "网络超时"});
            } else {
                resolve (responses[1]);
          }
          }).catch(error =>{
            reject(error);
          });

    })
  }

这个js专门与权限系统交互,查询用户的token,用户的权限等等。我这里主要定义了3个属性。token、routers、permissions,使用这三个实现对路由和页面元素的鉴权。当然我们还可以增加接口鉴权,等等

3.2 vux状态管理

上文所述查询到对应的权限之后,我们可以通过使用vuex将状态保存,利于我们项目之中进行使用。

3.2.1 自定义状态

通过自定义状态,定义应该交由vuex进行保存的状态


import { getAuth } from "./uniCallAuth"


const permission ={
    //各种状态
    state: {
        token:'',
        routes: [],
        permissions:[]
      },
    mutations:{
        //获得权限token
        AUTH_TOKEN: (state,token) =>{
            state.token = token
        },
        AUTH_PERMISSIONS: (state,permissions) =>{
            state.permissions = permissions
        },
        AUTH_ROUTERS: (state,routes) =>{
            state.routes = routes
        }

    },
    actions:{
        getUserAuth({commit},data){
            return new Promise(resolve => {
                getAuth(data).then(userData=>{
                    console.log("userData",userData)
                  //提交相关的状态
                  commit('AUTH_TOKEN',userData.token);
                  commit('AUTH_ROUTERS',userData.routes);
                  commit('AUTH_PERMISSIONS',userData.permissions);
                  console.log("用户状态已提交");
                  resolve();
                })
            })

        }

    }

}


export default permission

3.2.2 在vuex的store配置内添加我们新增的状态管理

在这里插入图片描述
具体使用状态的方法;
在这里插入图片描述

3.3 全局路由守卫鉴权

在用户登陆时,通过调用权限进行鉴权,鉴权结束后,vuex就存储了相应的权限状态,我们通过定义方法,对全局路由进行鉴权

Vue.prototype.$bus = new Vue();

Vue.prototype.$bus.$on('uniNavigateTo', options => {
  // 全局路由守卫的具体逻辑
  console.log("全局路由守卫起作用",options);

  let newString
  //截取url防止get请求拼参
  if(options.url.includes('?')){
    newString = options.url.substring(0, options.url.indexOf('?'));
  }else{
    newString = options.url;
  }
  

  //登陆页面直接跳转
  if(newString == '/pages/views/user/phoneLogin' || newString =='/pages/views/seller/NotLogin'){
    console.log("普通页面直接跳转");
    uni.navigateTo(options);
    return;
  }
  console.log("newString",newString);
  //判断是否具有页面跳转权限
  if(! checkRouter(newString,store.state.permission.routes)){
    // uni.showToast(String("没有权限"));
    console.log("无法跳转uniNavigateTo",store.state.permission.routes);
    return;
  }
  console.log("应该跳转页面");
  uni.navigateTo(options);

});


Vue.prototype.$bus.$on('uniSwitchTab', options => {
  console.log("底部全局路由守卫起作用",options);

  //截取url防止get请求拼参
  let newString
  //截取url防止get请求拼参
  if(options.url.includes('?')){
    newString = options.url.substring(0, options.url.indexOf('?'));
  }else{
    newString = options.url;
  }

//判断是否具有页面跳转权限
if(! checkRouter(newString,store.state.permission.routes)){
  // uni.showToast(String("没有权限"));
  console.log("无法跳转uniSwitchTab");
  return;
}
console.log("应该跳转页面");
uni.switchTab(options);

});

四:总结提升

本文通过研究若依系统的权限,实现了自己项目的鉴权,并且在若依的基础上进行了对应的二次开发。理清了前端鉴权的方式,并且进行了实现。大家如果需要前端鉴权,可以参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/656007.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

rust切片

这里s的不可变引用借用给了wordIndex,而s.clear()又想用可变引用,所以报错。而第一个例子中返回的usize并没有返回不可变引用。

客户端负载均衡工具Ribbon

一 什么是Ribbon Ribbon介绍 目前主流的负载方案分为以下两种: 集中式负载均衡,在消费者和服务提供方中间使用独立的代理方式进行负载,有硬件的(比如 F5),也有软件的(比如 Nginx)…

Ubuntu系统中分布式安装配置HBase-2.3.7

HBase是一个基于Hadoop的分布式列式数据库,可以存储海量的结构化和半结构化数据。本文介绍如何在三个Ubuntu系统上搭建一个HBase集群,并进行简单的数据操作。 在三个Ubuntu系统上分布式安装配置HBase-2.3.7,主要步骤包括: 准备工…

MySQL的执行原理

一、单表访问之索引合并 我们前边说过MySQL在一般情况下执行一个查询时最多只会用到单个二级索引,但存在有特殊情况,在这些特殊情况下也可能在一个查询中使用到多个二级索引,MySQL中这种使用到多个索引来完成一次查询的执行方法称之为&#…

Qgis加载在线XYZ瓦片影像服务的实践操作

目录 背景 一、XYZ瓦片相关知识 1、xyz瓦片金字塔 2、 瓦片编号 3、瓦片访问 二、在Qgis中加载在线地图 1、Qgis版本 2、瓦片加载 3、地图属性预览 总结 背景 在做电子地图应用的时候,很常见的会提到瓦片(tile)的概念,瓦片…

Java实训日志07

文章目录 八、项目开发实现步骤(十)创建应用程序类1、创建app子包2、创建Application类 (十一)创建窗口界面类1、创建主界面窗口(1)做一个空白的主界面窗口(2)退出时弹出消息框询问用…

【cutlass】cuTe layout操作

简介 cuTe提供了对Layout操作的算法,可以混合执行来构建更复杂的Layout操作,比如在其他layout之间切分和平铺layout 在host或者device上打印cuTe cuTe的打印函数可以在host和device端打印。cute::print 重载了几乎所有 CuTe 类型,包括指针…

MT8168/MTK8168核心板,4G安卓核心板

MT8168是一款集成度很高的高性能应用处理器,具有低功耗特性,并且提供卓越的多媒体体验,适用于平板电脑、智能手持终端以及智能家居和物联网应用等嵌入式设备。这款芯片采用了先进的12纳米工艺,将四核Arm-Cortex A53 MPCore TM CPU…

关于JAVA中 方法中无法改变String的分析

package com.atguigu.String01;public class String01 {public static void main(String[] args) {// 字符串不变性String str "hello";// 对象成员数组是finalchange(str);System.out.println("change后的str:"str);int[] a {1,3,5,7,9};int[] b {2,3,…

【V4L2】 v4l2框架分析之v4l2_fh

一、v4l2_fh简介 🔺相关源码文件: /drivers/media/v4l2-fh.c /drivers/media/v4l2-fh.h 在V4L2中,struct v4l2_fh结构用于保存V4L2框架中使用的文件句柄(File Handle)的数据,即每个打开的视频设备都会对…

微信小程序开发入门学习01-TDesign模板解读

目录 1 使用模板创建小程序2 app.json3 页面布局总结 原来我们使用微信开发者工具,比较困难的是前端框架的选择上,官方也没有提供一套框架供我们使用,最近开发者工具已经提供了一套前端框架,后续我们开发的效率会因为使用模板提高…

Linux-线程的同步与互斥

线程的同步与互斥 进程/线程间的互斥相关背景概念互斥量互斥量接口互斥量的初始化互斥量的销毁加锁和解锁 改善抢票系统互斥量原理 可重入与线程安全重入和线程安全的概念常见线程不安全情况常见线程安全的情况常见不可重入情况常见可重入情况可重入与线程安全的关系可重入与线…

Spring Security系列之认证(Authentication)架构

文章目录 架构主要组件SecurityContextHolderAuthenticationAuthenticationManagerProviderManagerAuthenticationProviderAuthenticationEntryPointAbstractAuthenticationProcessingFilter 架构主要组件 SecurityContextHolder - SecurityContextHolder 是 Spring Security …

【tensorflow】连续输入的神经网络模型训练代码

【tensorflow】连续输入的神经网络模型训练代码 全部代码 - 复制即用 训练输出 代码介绍 全部代码 - 复制即用 from sklearn.model_selection import train_test_split import tensorflow as tf import numpy as np from keras import Input, Model, Sequential from keras.l…

try-catch-finally中的四大坑

目录 1.坑1:finally中使用return 2.坑2:finally中的代码好像“不执行” 3.坑3:finally中的代码“非最后”执行 4.坑4:finally中的代码真的“不执行” 在 Java 语言中 try-catch-finally 看似简单,但想要真正的“掌…

对现在的生活不满意?《围城》给你个人,婚姻,爱情的启示

杨绛先生在100岁感言的时候说,我们曾如此期盼外界的认可,到最后才知道:世界是自己的,与他人毫无关系!百岁老人的感言,清晰透彻地道出了人生的真相。我们每个人都是生活于关系之中的,在错综复杂的…

华为OD机试真题 JavaScript 实现【找车位】【2023 B卷 100分】,附详细解题思路

一、题目描述 停车场有一横排车位,0代表没有停车,1代表有车。至少停了一辆车在车位上,也至少有一个空位没有停车。 为了防剐蹭,需为停车人找到一个车位,使得距停车人的车最近的车辆的距离是最大的,返回此…

【tensorflow】连续输入的线性回归模型训练代码

【tensorflow】连续输入的感知机模型训练 全部代码 - 复制即用 训练输出 代码介绍 全部代码 - 复制即用 from sklearn.model_selection import train_test_split import tensorflow as tf import numpy as np from keras import Input, Model, Sequential from keras.layers …

2023ciscn初赛 Unzip

参考&#xff1a; 奇安信攻防社区-2021深育杯线上初赛官方WriteUp-Web篇 1.打开环境 2.上传一个文件&#xff0c;得到以下源码&#xff0c;分析一下8 <?php error_reporting(0); highlight_file(__FILE__);$finfo finfo_open(FILEINFO_MIME_TYPE); //使用 PHP 内置函数…

【软考系统规划与管理师笔记】第7篇 IT服务运营管理

这章也基本上是纯概念&#xff0c;整体上来说系统规划与管理师考试&#xff0c;以概念记忆为主。课本上的知识点往往告诉我们该怎么做&#xff0c;但是如何确保执行到位&#xff0c;如何主动激发员工、客户执行到位&#xff0c;往往还是空白&#xff1f;&#xff0c;作为考试记…