권한 제어의 백 오피스 시스템을 달성하는 방법 VUE

I. 서론

프로젝트를 광고에서, 권한 관리 카드의 역할은 매우 어려움 긴 시간이다. 첫째, 포인트의 미세한 입자 크기에 따라 두 부분으로 분할 액세스 제어를 결정 :

  • 액세스 제어 권한 인터페이스
  • 제어 권한 페이지

    • 메뉴 페이지에 액세스 할 수 있는지 여부
    • 버튼 페이지 (추가, 삭제, 변경) 액세스 제어 여부

여기에서 우리는 이들 두 개의 액세스 제어를 달성하는 방법이다 본다.

둘째, 인터페이스 액세스 제어 권한

인터페이스는 사용자의 권한을 확인합니다. 당신이 때마다 인터페이스이 토큰을 가지고 프론트 데스크에 전화해야 할 때 일반적으로 때 수신 서버의 요구에 로그온 나중에 다음 토큰을 반환하고,

그런 다음 서버는 통해 액세스 할 수있는 경우, 비교를 위해 토큰을 획득 한 후.

기존 방식은 콜백에서 백그라운드로 성공적으로 로그인이 토큰 스토리지에 직접 반환되는 sessionStorag​e토큰 헤더에 대한 요청이 배경에 기절 할 때 다음과 같이 다음 :

this.$http({
          method: 'get',
          url: 'test/query?id=20',
          withCredentials: true,
          headers: {
            token: sessionStorage.getItem('token'),
            name: sessionStorage.getItem('name')    //应后台需求传的用户名
          }
        }).then(response => {
          //请求成功后的操作
        })

나중에 토큰 Axios의 일부 기사에서 발견 직접 요격에 삽입 할 수있는 config.headers.Authorization전달 된 세계로. 다음 코드 섹션은 다음과 같습니다

//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

셋째, 액세스 제어 페이지

이미 액세스 제어 페이지가 2 개로 나누어 져있어, 말했다 :

  • 메뉴 페이지에 액세스 할 수 있는지 여부
  • 버튼 페이지 (추가, 삭제, 변경) 액세스 제어 여부

이러한 권리는 일반적으로 데이터베이스에 기록을 저장 한 후, 고정 구성 페이지에서 수행된다.


버튼 권한은 제외하고, 구현 페이지 액세스는 두 가지로 나눌 수 있습니다 :

  • 사용자가 메뉴에 액세스 할 때, 자신의 권한 내에 있지있는 권한 제안, 모든 메뉴를보기
  • URL을 통해 사용자 필수 액세스, (404)에 직접 갈 것입니다 경우 메뉴에 액세스 할 수 있습니다 만 현재 사용자의 범위 내에서보기

나는 그 수를 여러 가지 의미 후 표시를 가리 수 없기 때문에, 내가 그것을 재생할 수 있도록? 확실히 이상의 프로그램이 좋은 사용자 경험에 맞춰 종합적인 검토 후, 순의 시력 소위.

음, 지금은 일종의 무엇 대략적인 페이지 액세스 프로세스 아웃 :

프로세스 권한

빗질하는 과정 종료 후 우리는 구체적으로 쓰기 시작했다.

1, 라우팅 테이블을 생성

라우팅 테이블이 실제로 어려운 일이 아니다 만들기, 따라 VUE 라우터 공식 문서의 예하면 줄에 직접 작성합니다. 그러나 일부 페이지가 액세스를 필요로하지 않기 때문에,

당신이 로그인 할 필요가 그래서 다른 페이지 변수 또는 파일, 캔에 서면 허가가 필요하지만, (404), 유지 보수 및 다른 페이지는 기본 경로를 작성

효과적으로 지속적인 유지 보수 압력을 줄이기 위해.

다음 코드하는 index.js를 붙여 비동기식 라우팅은 너무 많은 공간을 차지하지 않도록, 양을 줄일 수 있습니다.

// 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),
      },
    ]
  }
  ]
];

참고 : 매우 지역주의 필요가있다은 404 페이지 constantRouterMap이 페이지가 차단되도록 404 개 자세한 질문 뒤에 (404)를 선언 조립하는 경우, 마지막으로로드를 참조 할 수 있어야합니다 와일드 카드를 가지고 때 addRoutes을 404의 노선은 일을하지 않습니다

이 페이지에 액세스

일반 페이지 액세스 과정에서 일종의 우리를 시작 부분에. 우리가 먼저 핵심 구성 요소를 구현하자

액세스 프로세스

우리는 먼저 우리가 vuex 상태 관리에 노출되는 사용자 권한 목록을 얻을, 공식 문서가 너무 많이, 아래의 코드를 참조하십시오되지 여기에 설명에 자세히 설명되어 있습니다 :

// 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
})

글쎄, 우리는 이제 vuex에 다음의 데이터를 저장하기 위해, 올바른 데이터를 얻기 위해 다시 요청, 우리는 비동기식 라우팅 테이블과 일치하는 데이터를 반환하기 전에 쓰기에 일치하는 결과 및 정적 라우팅 테이블이 최종 실제 라우팅 테이블에 개방, 결합 사용해야 .

가장 중요한 중 하나는 VUE-router2.2.0 새 버전이 추가 된 addRoutes 방법, 우리는 공식 문서가이 방법을 설명하는 방법을 살펴의 사용이다 :

router.addRoutes (노선) 2.2.0+ 
동적으로 더 라우팅 규칙을 추가합니다. 매개 변수는 옵션의 요구 사항에 맞춰 경로의 배열이어야합니다.

우리는 지금 addRoutes 경로 일치를 사용하여 시작할 수 있습니다. 아래의 코드를보고 :

// 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])
  })
}

그럼 우리가 탐색 후크 쓰기

// 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('/')
    }
  }
});

여기에 우리가 방문한 페이지의 액세스 제어를 완료 한 후, 우리는 조작 버튼의 일부의 권리를 설명해야한다.

넷째, 운영 권한 데이터

당신이 우리의 이전 라우팅 구성을 기억하고 추가 코드를 수행,하자가 밖을 내다 :

//异步路由(需要权限的页面)
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),
      },
    ]
  }
  ]
];

각 경로 페이지에 대한 메타 필드를 높입니다. 여기에 세부 사항에 권한 필드 할당에 RouterMatch 매칭 기능. 이는 각 페이지의 노선 객체에서이 필드를 얻을 것이다.

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 @click="upload" v-allow="'3'"></a> /* 3代表一个上传权限的ID,权限中有3则显示按钮 */

우리는 액세스 VUE로는 vnode의 방법을 사용하여, 글로벌 직접 명령을 등록했다. 다음과 같이 코드입니다 :

//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)
    }
  }
})

지금까지, 액세스 제어 프로세스가 완전히 완료되었고, 결국 우리는 액세스 제어 그것의 전체 흐름도 봐.

다섯 전체 라우팅 제어 흐름도

플로우 차트

VI. 참고

  1. 뷰 + ElementUI 손 라인과 웹 사이트 배경 관리 권한 제어
  2. 제어 선 및 권한 VUE의 배경으로 당신과 함께 손 터치는 손

추천

출처www.cnblogs.com/jlfw/p/11837830.html