Ce que cet article vous apporte concerne la méthode de mise en œuvre du contrôle des autorisations du système de gestion en arrière-plan dans Vue. Il a une certaine valeur de référence. Les amis dans le besoin peuvent s'y référer.
Dans le projet de machine publicitaire, la gestion des autorisations de rôle a été un point difficile qui est bloqué depuis longtemps. Tout d'abord, le contrôle des autorisations que nous avons déterminé est divisé en deux parties, qui sont plus détaillées en fonction de la taille des granules :
Contrôle des autorisations pour l'accès à l'interface
Contrôle des autorisations de page
Si la page du menu est accessible
Boutons de la page ( ajouter, supprimer, modifier ) les contrôles d'autorisation s'affichent
Voyons comment implémenter ces contrôles d'autorisation.
Les autorisations d'interface sont une vérification des utilisateurs. Normalement, lorsque l'utilisateur se connecte, le serveur doit rendre un Token à la réception, puis la réception doit apporter ce Token à chaque fois qu'elle appelle l'interface
Ensuite, le serveur obtient ce Token et. le compare. S’il est réussi, il est accessible.
La méthode existante consiste à stocker le jeton renvoyé par l'arrière-plan directement dans sessionStorage
dans le rappel d'une connexion réussie, puis à retirer le jeton, à le placer dans les en-têtes et à le transmettre à l'arrière-plan lors de la demande. Le code est le suivant :
this.$http({ method: 'get', url: 'test/query?id=20', withCredentials: true, headers: { token: sessionStorage.getItem('token'), name: sessionStorage.getItem('name') //应后台需求传的用户名 } }).then(response => { //请求成功后的操作 })
Plus tard, j'ai trouvé dans certains articles qu'axios peut directement insérer le Token dans config.headers.Authorization
dans l'intercepteur en tant que passe globale. Voici la partie code :
//main.js import axios from 'axios' // 实例化Axios,并进行超时设置 const service = axios.create({ timeout: 5000 }) // baseURL // axios.defaults.baseURL = 'https://api.github.com'; // http request 拦截器 // 每次请求都为http头增加Authorization字段,其内容为token service.interceptors.request.use( config => { if (store.state.user.token) { config.headers.Authorization = `token ${store.state.user.token}`; } return config }, err => { return Promise.reject(err) } ); export default service
Comme mentionné précédemment, le contrôle des autorisations de page est divisé en deux types :
Si la page du menu est accessible
Si le contrôle d'autorisation des boutons (ajouter, supprimer, modifier) dans la page est affiché
Ces autorisations sont généralement configurées sur une page fixe, puis sauvegardées et enregistrées dans la base de données
Ne parlons pas des autorisations des boutons pour le moment. Les autorisations d'accès aux pages peuvent être divisées de deux manières dans la mise en œuvre :
Afficher tous les menus. Lorsque l'utilisateur accède à un menu qui ne fait pas partie de ses autorisations, un message indiquant des autorisations insuffisantes s'affiche. >Affiche uniquement les menus dans les autorisations auxquelles l'utilisateur actuel peut accéder. Si l'utilisateur accède au menu via l'URL, l'accès forcé mènera directement à 404
Puisqu'il ne peut pas être cliqué une fois qu'il est cliqué. affiché, qu'est-ce que ça veut dire de me taquiner ? Comme le dit le proverbe, « hors de vue » est hors de vue. Après un examen approfondi, la deuxième option est nettement plus conforme à une bonne expérience utilisateur.
Après avoir réglé le processus, nous commencerons Écriture détaillée. 1. Créer une table de routage
Créer une table de routage n'est en fait pas difficile. Suivez simplement l'exemple donné dans le document officiel de vue-router et écrivez-le directement. Cependant, comme certaines pages ne nécessitent pas d'autorisations d'accès,
réduire efficacement la pression de maintenance ultérieure.
Le code d'index.js sera collé ci-dessous. Le routage asynchrone sera réduit de manière appropriée pour éviter de prendre trop de place.
Remarque : une chose qui nécessite une attention particulière ici est que la page 404 doit être chargée en dernier. Si 404 est déclaré avec constantRouterMap, toutes les pages suivantes seront interceptées et recevront 404. Questions détaillées Voir addRoutes. lorsque vous avez une route générique pour les 404, cela ne fonctionne pas 2. Autorisations d'accès aux pages// router/index.js import Vue from 'vue' import Router from 'vue-router' import App from '@/App' import store from '../store/index' Vue.use(Router); //手动跳转的页面白名单 const whiteList = [ '/' ]; //默认不需要权限的页面 const constantRouterMap = [ { path: '/', name: '登录', component: (resolve) => require(['@/components/login'], resolve) }, { path: '/index', name: 'nav.Home', component: (resolve) => require(['@/components/index'], resolve) }, { path: '/templateMake', name: '模板制作', component: (resolve) => require(['@/components/Template/templateMake'], resolve) }, { path: '/programMack', name: '节目制作', component: (resolve) => require(['@/components/Template/programMack'], resolve) }, { path: '/release', name: '节目发布', component: (resolve) => require(['@/components/Program/release'], resolve) } ] //注册路由 export const router = new Router({ routes: constantRouterMap }); //异步路由(需要权限的页面) export const asyncRouterMap = [ { path: '/resource', name: 'nav.Resource', meta: { permission: [] }, component: (resolve) => require(['@/components/Resource/resource'], resolve) }, { path: '/template', name: 'nav.Template', meta: { permission: [] }, component: (resolve) => require(['@/components/Template/template'], resolve) }, { path: '/generalSet', name: 'nav.System', meta: { permission: [] }, component: (resolve) => require(['@/components/SystemSet/generalSet'], resolve) }, { path: '', name: 'nav.Log', component: App, children: [ { path: '/userLog', name: 'nav.UserLog', meta: { permission: [] }, component: (resolve) => require(['@/components/Log/userLog'], resolve), }, { path: '/operatingLog', name: 'nav.SystemLog', meta: { permission: [] }, component: (resolve) => require(['@/components/Log/operatingLog'], resolve), }, ] } ] ];
Au début, nous avons réglé un processus approximatif d'autorisations d'accès aux pages. Ensuite, nous implémentons d'abord la partie principale :
Nous obtenons d'abord la liste des autorisations des utilisateurs. Ici, nous entrerons en contact avec la gestion du statut de vuex. la documentation officielle est une introduction détaillée, je ne la décrirai pas trop ici Veuillez regarder le code ci-dessous :
D'accord, maintenant nous demandons l'arrière-plan pour obtenir les données d'autorisation et stocker les données dans vuex. Ensuite, nous devons utiliser les données renvoyées pour faire correspondre la table de routage asynchrone écrite précédemment et combiner les résultats correspondants avec la table de routage statique pour créer la table de routage réelle finale. La plus critique est d'utiliser la méthode addRoutes nouvellement ajoutée dans la version vue-router2.2.0. Voyons comment la documentation officielle explique cette méthode :// store/index.js import Axios from 'axios' import Vue from 'vue' import Vuex from 'vuex' Vue.use(Vuex); const axios = Axios.create(); const state = { mode: 'login', list: [] }; const getters = {}; const mutations = { setMode: (state, data) => { state.mode = data }, setList: (state, data) => { state.list = data } }; const actions = { // 获取权限列表 getPermission({commit}) { return new Promise((resolve, reject) => { axios({ url: '/privilege/queryPrivilege?id=' + sessionStorage.getItem('privId'), methods: 'get', headers: { token: sessionStorage.getItem('token'), name: sessionStorage.getItem('name') } }).then((res) => { // 存储权限列表 commit('setList', res.data.cust.privileges[0].children); resolve(res.data.cust.privileges[0].children) }).catch(() => { reject() }) }) } }; export default new Vuex.Store({ state, mutations, actions, getters })
router.addRoutes(routes) 2.2. 0+
Ajoutez dynamiquement plus de règles de routage. Le paramètre doit être un tableau correspondant aux exigences de l'option routes. Ensuite, nous pouvons maintenant commencer à utiliser addRoutes pour la correspondance d'itinéraire. Regardons le code ci-dessous :// router/index.js /** * 根据权限匹配路由 * @param {array} permission 权限列表(菜单列表) * @param {array} asyncRouter 异步路由对象 */ function routerMatch(permission, asyncRouter) { return new Promise((resolve) => { const routers = []; // 创建路由 function createRouter(permission) { // 根据路径匹配到的router对象添加到routers中即可 permission.forEach((item) => { if (item.children && item.children.length) { createRouter(item.children) } let path = item.path; // 循环异步路由,将符合权限列表的路由加入到routers中 asyncRouter.find((s) => { if (s.path === '') { s.children.find((y) => { if (y.path === path) { y.meta.permission = item.permission; routers.push(s); } }) } if (s.path === path) { s.meta.permission = item.permission; routers.push(s); } }) }) } createRouter(permission) resolve([routers]) }) }
是否还记得前面的路由配置中我们多出来的一个代码,下面我们拿出来看看:
//异步路由(需要权限的页面) export const asyncRouterMap = [ { path: '/resource', name: 'nav.Resource', meta: { permission: [] }, component: (resolve) => require(['@/components/Resource/resource'], resolve) }, { path: '/template', name: 'nav.Template', meta: { permission: [] }, component: (resolve) => require(['@/components/Template/template'], resolve) }, { path: '/generalSet', name: 'nav.System', meta: { permission: [] }, component: (resolve) => require(['@/components/SystemSet/generalSet'], resolve) }, { path: '', name: 'nav.Log', component: App, children: [ { path: '/userLog', name: 'nav.UserLog', meta: { permission: [] }, component: (resolve) => require(['@/components/Log/userLog'], resolve), }, { path: '/operatingLog', name: 'nav.SystemLog', meta: { permission: [] }, component: (resolve) => require(['@/components/Log/operatingLog'], resolve), }, ] } ] ];
为每个路由页面增加meta字段。在routerMatch函数中将匹配到的详细权限字段赋值到这里。这样在每个页面的route对象中就会得到这个字段。
asyncRouter.find((s) => { if (s.path === '') { s.children.find((y) => { if (y.path === path) { //赋值 y.meta.permission = item.permission; routers.push(s); } }) } if (s.path === path) { s.meta.permission = item.permission; routers.push(s); } })
接下来我们编写一个vue自定义指令对页面中需要进行鉴权的元素进行判断,比如类似这样的:
<a></a> /* 3代表一个上传权限的ID,权限中有3则显示按钮 */
我们直接注册一个全局指令,利用vnode来访问vue的方法。代码如下:
//main.js //按扭权限指令 Vue.directive('allow', { inserted: (el, binding, vnode) => { let permissionList = vnode.context.$route.meta.permission; if (!permissionList.includes(binding.value)) { el.parentNode.removeChild(el) } } })
至此为止,权限控制流程就已经完全结束了,在最后我们再看一下完整的权限控制流程图吧.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!