Der Inhalt dieses Artikels befasst sich mit der Methode zur Implementierung der Berechtigungskontrolle des Hintergrundverwaltungssystems. Ich hoffe, dass er für Sie hilfreich ist.
Im Werbemaschinenprojekt war die Rollenberechtigungsverwaltung ein schwieriger Punkt, der schon lange feststeckt. Zunächst ist die von uns festgelegte Berechtigungssteuerung in zwei Teile unterteilt, die je nach Granulatgröße detaillierter sind:
Berechtigungssteuerung für den Schnittstellenzugriff
Seitenberechtigungskontrolle
Ob auf die Seite im Menü zugegriffen werden kann
Schaltflächen auf der Seite ( (Hinzufügen, Löschen, Ändern) der Berechtigungssteuerung wird angezeigt.
Schauen wir uns an, wie diese Berechtigungskontrollen implementiert werden.
Schnittstellenberechtigungen sind die Überprüfung von Benutzern. Normalerweise muss der Server beim Anmelden des Benutzers ein Token an die Rezeption zurückgeben, und die Rezeption muss dieses Token dann jedes Mal mitbringen, wenn sie die Schnittstelle aufruft.
Dann erhält der Server dieses Token und vergleicht es. Wenn es übergeben wird, kann darauf zugegriffen werden.
Die bestehende Methode besteht darin, das vom Hintergrund zurückgegebene Token im Rückruf einer erfolgreichen Anmeldung direkt in sessionStorage
zu speichern, das Token dann herauszunehmen, in Header einzufügen und bei der Anforderung an den Hintergrund weiterzuleiten. Der Code lautet wie folgt:
this.$http({ method: 'get', url: 'test/query?id=20', withCredentials: true, headers: { token: sessionStorage.getItem('token'), name: sessionStorage.getItem('name') //应后台需求传的用户名 } }).then(response => { //请求成功后的操作 })
Später wurde in einigen Artikeln festgestellt, dass Axios das Token als globalen Pass direkt in config.headers.Authorization
im Interceptor einfügen kann. Das Folgende ist der Codeteil:
//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
Wie bereits erwähnt, ist die Seitenberechtigungssteuerung in zwei Typen unterteilt:
Ob auf die Seite im Menü zugegriffen werden kann
Die Berechtigungssteuerung der Schaltflächen (Hinzufügen, Löschen, Ändern) auf der Seite zeigt an, ob
Diese Berechtigungen werden im Allgemeinen auf einer festen Seite angezeigt und dann in der Datenbank gespeichert und aufgezeichnet.
Die Schaltflächenberechtigungen können bei der Implementierung zunächst nicht erwähnt werden:
Alle Menüs anzeigen, die nicht innerhalb seiner eigenen Berechtigungen liegen, werden unzureichende Berechtigungen angezeigt
Nur die Menüs anzeigen innerhalb der Berechtigungen, auf die der aktuelle Benutzer zugreifen kann, wird er direkt zu 404 weitergeleitet
Da es nach der Anzeige nicht angeklickt werden kann, was bewirkt es? Willst du mich ärgern? Wie das Sprichwort sagt: Aus den Augen ist man aus dem Sinn. Nach eingehender Überlegung entspricht Option zwei definitiv mehr einer guten Benutzererfahrung.
Okay, lass uns jetzt den allgemeinen Prozess der Seitenzugriffsrechte klären:
Nachdem wir den Prozess geklärt haben, beginnen wir Ausführliches Schreiben.
Das Erstellen einer Routing-Tabelle ist eigentlich nicht schwierig. Folgen Sie einfach dem Beispiel im offiziellen Vue-Router-Dokument und schreiben Sie es direkt. Da jedoch für einige Seiten keine Zugriffsberechtigungen erforderlich sind,
, müssen Sie Anmelde-, 404-, Wartungs- und andere Seiten in die Standardroute schreiben und andere Seiten schreiben, die Berechtigungen für eine Variable oder eine Datei erfordern. Dadurch kann
der nachfolgende Wartungsdruck effektiv reduziert werden.
Der Code von index.js wird unten eingefügt. Das asynchrone Routing wird entsprechend reduziert, um zu vermeiden, dass es zu viel Platz beansprucht.
// 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), }, ] } ] ];
Hinweis: Eine Sache, die hier besonders beachtet werden muss, ist, dass die 404-Seite zuletzt geladen werden muss. Wenn 404 zusammen mit „constantRouterMap“ deklariert wird, werden alle nachfolgenden Seiten abgefangen und erhalten 404. Einzelheiten zu den Problemen finden Sie unter addRoutes wenn Sie eine Wildcard-Route für 404s haben, funktioniert das nicht
Zu Beginn haben wir einen groben Prozess für die Seitenzugriffsrechte geklärt. Als nächstes implementieren wir zuerst den Kernteil:
Wir werden zuerst die Benutzerberechtigungsliste kontaktieren Die offizielle Dokumentation ist eine ausführliche Einführung, ich werde sie hier nicht zu sehr beschreiben, schauen Sie sich bitte den folgenden Code an:
// 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 })
Okay, jetzt fordern wir den Hintergrund an, um die Berechtigungsdaten abzurufen und die Daten in vuex Next zu speichern Wir müssen die zurückgegebenen Daten zum Abgleich verwenden. Die geschriebene asynchrone Routing-Tabelle kombiniert die Übereinstimmungsergebnisse mit der statischen Routing-Tabelle, um die endgültige tatsächliche Routing-Tabelle zu bilden.
Am wichtigsten ist die Verwendung der in der Version vue-router2.2.0 neu hinzugefügten Methode addRoutes. Sehen wir uns an, wie die offizielle Dokumentation diese Methode erklärt:
router.addRoutes(routes) 2.2. 0+
Fügen Sie dynamisch weitere Routing-Regeln hinzu. Der Parameter muss ein Array sein, das den Anforderungen der Routenoption entspricht.
Dann können wir jetzt damit beginnen, addRoutes für den Routenabgleich zu verwenden. Schauen wir uns den folgenden Code an:
// 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]) }) }
Dann schreiben wir den Navigations-Hook
// router/index.js router.beforeEach((to, form, next) => { if (sessionStorage.getItem('token')) { if (to.path === '/') { router.replace('/index') } else { console.log(store.state.list.length); if (store.state.list.length === 0) { //如果没有权限列表,将重新向后台请求一次 store.dispatch('getPermission').then(res => { //调用权限匹配的方法 routerMatch(res, asyncRouterMap).then(res => { //将匹配出来的权限列表进行addRoutes router.addRoutes(res[0]); next(to.path) }) }).catch(() => { router.replace('/') }) } else { if (to.matched.length) { next() } else { router.replace('/') } } } } else { if (whiteList.indexOf(to.path) >= 0) { next() } else { router.replace('/') } } });
An diesem Punkt haben wir die Berechtigungskontrolle für den Seitenzugriff abgeschlossen. Als nächstes erklären wir den Berechtigungsteil des Vorgangs Taste.
是否还记得前面的路由配置中我们多出来的一个代码,下面我们拿出来看看:
//异步路由(需要权限的页面) 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) } } })
至此为止,权限控制流程就已经完全结束了,在最后我们再看一下完整的权限控制流程图吧.
Das obige ist der detaillierte Inhalt vonMethoden zum Implementieren der Berechtigungskontrolle des Hintergrundverwaltungssystems in Vue. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!