Vue 경로 권한 제어 분석

9267 단어 vue경로권한
머리말
저 는 회사 에서 주로 백 스테이지 시스템 의 개발 을 책임 집 니 다.그 중에서 경로 와 권한 검증 은 매우 중요 하고 기본 적 인 일환 입 니 다.실제 개발 프로젝트 에서 로그 인 과 경로 권한 에 대한 통 제 는 vue-element-admin 이라는 스타 프로젝트 를 참조 하고 이 를 바탕 으로 업 무 를 통합 시 켰 습 니 다.그 다음 에 저 는 이 프로젝트 를 예 로 들 어 전체 경로 와 권한 검증 과정 을 자세히 분석 하고 이 지식 에 대한 정리 라 고 할 수 있 습 니 다.
프로젝트 전체 디 렉 터 리 구조
오늘 주제 에 들 어가 기 전에 우 리 는 먼저 전체 항목,src 디 렉 터 리 아래 의 것 을 정리 합 니 다.
  • api:인터페이스 요청
  • assets:정적 자원
  • components:범용 구성 요소
  • directive:사용자 정의 명령
  • filter:사용자 정의 필터
  • icons:아이콘
  • layout:레이아웃 구성 요소(페이지 구조 핵심)
  • 라 우 터:경로 설정(경로 권한 핵심 모듈)
  • store:상태 관리
  • 스타일:스타일 파일
  • utils:도구 방법
  • 조회 수:페이지 구성 요소
  • permission.js 권한 관리
  • 이 프로젝트 에 관심 이 있 는 학생 들 은 스스로 목적 성 있 게 공부 할 수 있 고 권한 검증 기능 을 제외 하고 재 미 있 는 기능 도 많이 포함 되 어 있어 많은 것 을 배 울 수 있 을 것 이 라 고 믿 습 니 다.
    루트 권한 제어 논리
    루트 처리 흐름 도

    루트 처리 원본 분석
    우선 permission.js 파일 을 찾 았 습 니 다.전역 경 로 를 지 키 는 것 도 권한 에서 매우 중요 한 핵심 코드 입 니 다.여러분 의 편 의 를 위해 서,경로 와 관련 된 코드 만 발췌 하 였 습 니 다.
    
    import router from './router'
    import store from './store'
    import { Message } from 'element-ui'
    import NProgress from 'nprogress' // progress bar
    import 'nprogress/nprogress.css' // progress bar style
    import { getToken } from '@/utils/auth' // get token from cookie
    
    NProgress.configure({ showSpinner: false }) // NProgress Configuration
    
    const whiteList = ['/login', '/auth-redirect'] //      
    
    router.beforeEach(async(to, from, next) => {
     // start progress bar
     NProgress.start()
     //  token
     if (hasToken) {
     if (to.path === '/login') 
      //        /login,      
      next({ path: '/' })
      NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
     } else {
      // determine whether the user has obtained his permission roles through getInfo
      const hasRoles = store.getters.roles && store.getters.roles.length > 0
      if (hasRoles) {
       next()
      } else {
      try {
       //       
       const { roles } = await store.dispatch('user/getInfo')
       //        ,      
       const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
       //        (                 )
       router.addRoutes(accessRoutes)
       //     
       next({ ...to, replace: true })
      } catch (error) {
       //   token
       await store.dispatch('user/resetToken')
       Message.error(error || 'Has Error')
       //         
       next(`/login?redirect=${to.path}`)
       NProgress.done()
      }
      }
     }
     } else {
     //   token
     if (whiteList.indexOf(to.path) !== -1) {
      //        ,          ,    
      next()
     } else {
      //           ,         .
      next(`/login?redirect=${to.path}`)
      NProgress.done()
     }
     }
    })
    
    router.afterEach(() => {
     // finish progress bar
     NProgress.done()
    })
    
    코드 에 있 는/login?redirect=${jto.path}을 알 수 있 습 니 다.여기 있 는 redirect 인 자 는 주로 사용자 로그 인 성공 후 점프 하 는 페이지 경로 에 사 용 됩 니 다.구체 적 인 기능 은/views/login/index.vue 파일 에서
    
    watch: {
     $route: {
     handler: function(route) {
      const query = route.query
      if (query) { //      
      this.redirect = query.redirect
      this.otherQuery = this.getOtherQuery(query)
      }
     },
     immediate: true
     }
    },
    // methods  :
    handleLogin() { //     
     this.$refs.loginForm.validate(valid => {
     if (valid) { //          
      this.$store.dispatch('user/login', this.loginForm)
      .then(() => {
       //      this.redirect      
       this.$router.push({ path: this.redirect || '/', query: this.otherQuery })
       this.loading = false
      })
     } else {
      // ..
     }
     })
    },
    
    동적 경로 설정
    경로 의 정 의 를 살 펴 보 겠 습 니 다./src/router/index.js 파일 에서.
    
    export const constantRoutes = [ //            ,        
     //       
    ]
    export const asyncRoutes = [ //        meta.roles       ,        
     {
     path: '/permission',
     component: Layout,
     redirect: '/permission/page',
     alwaysShow: true, // will always show the root menu
     name: 'Permission',
     meta: {
      title: 'Permission',
      icon: 'lock',
      roles: ['admin', 'editor'] //   roles       
     },
     // ...
     }
    ]
    
    동적 으로 루트 를 추가 할 때 본질 적 으로 사용자 의 역할 정보 에 따라 asyncRoutes 루트 설정 그룹 에서 루트 를 선별 하여 해당 하 는 루트 를 찾 아 constantRoutes 와 합병 하여 최신 루트 를 생 성 한다.
    동적 추가 루트 논리 도

    동적 경로 소스 코드 분석
    코드 입구:permission.js
    
    const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
    
    permission/generateRoutes 방법 입구 파일:/strore/modules/permissions.js
    
    import { asyncRoutes, constantRoutes } from '@/router'
    const state = {
     routes: [],
     addRoutes: []
    }
    
    const mutations = {
     SET_ROUTES: (state, routes) => {
     state.addRoutes = routes
     state.routes = constantRoutes.concat(routes)
     }
    }
    
    const actions = {
     generateRoutes({ commit }, roles) {
     return new Promise(resolve => {
      let accessedRoutes
      if (roles.includes('admin')) {
      //      admin,    admin,           
      accessedRoutes = asyncRoutes || [] 
      } else {
      //        ,         roles         
      accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
      }
      //          vuex 
      commit('SET_ROUTES', accessedRoutes)
      // resolve  
      resolve(accessedRoutes)
     })
     }
    }
    
    비동기 경 로 를 선별 하고 최종 결 과 를 vuex 에 저장 하 며 결 과 를 resolve 합 니 다.
    
    export function hasPermission(roles, route) {
     if (route.meta && route.meta.roles) { //     meta.roles
     //   meta.roles               ,         
     return roles.some(role => route.meta.roles.includes(role))
     } else {
     //    meta      meta.roles,        ,    
     return true
     }
    }
    
    export function filterAsyncRoutes(routes, roles) {
     const res = []
    
     routes.forEach(route => {
     const tmp = { ...route }
     if (hasPermission(roles, tmp)) { //                    
      if (tmp.children) {
      //     children,         
      tmp.children = filterAsyncRoutes(tmp.children, roles)
      }
      //             res 
      res.push(tmp)
     }
     })
     return res
    }
    
    마지막 으로/permission.js 파일 로 돌아 가기
    
    const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
    //    accessRoutes         ,
    //     route.addRoutes constRoutes accessRoutes    ,         
    router.addRoutes(accessRoutes)
    
    확장-단추 권한
    루트 권한 제어 의 기본 프로 세 스 가 분석 되 었 으 니 다음 에 프로젝트 의 단추 권한 제어 의 실현 을 살 펴 보 자.실현 도 비교적 간단 하 다.
    
        
    <div v-permission="['admin','editor']"></div>
    import store from '@/store'
    
    function checkPermission(el, binding) {
     const { value } = binding
     //  store          ,        
     const roles = store.getters && store.getters.roles
    
     if (value && value instanceof Array) { //            ,     
     if (value.length > 0) {
      const permissionRoles = value
      //      permissionRoles ,   roles        ,      
      const hasPermission = roles.some(role => {
      return permissionRoles.includes(role)
      })
      //          ,   。
      // v-permission                
      if (!hasPermission) {
      el.parentNode && el.parentNode.removeChild(el)
      }
     }
     } else {
     throw new Error(`need roles! Like v-permission="['admin','editor']"`)
     }
    }
    
    export default {
     inserted(el, binding) {
     checkPermission(el, binding)
     },
     update(el, binding) {
     checkPermission(el, binding)
     }
    }
    
    
    총결산
    존재 토 큰
           사용자 역할 정보 가 존재 하면 이 사용자 가 최종 적 으로 접근 할 수 있 는 경로 가 생 성 되 었 음 을 설명 하고 직접 실행 할 수 있 습 니 다.
           사용자 정보 없 음
                  1.사용자 정보 인 터 페 이 스 를 호출 하여 사용자 정 보 를 얻 고 vuex 에 사용자 정 보 를 저장 합 니 다.
                  2.사용자 역할 판단
  • 관리자 라면 모든 모듈 에 접근 권한 이 있 습 니 다
  • 관리자 가 아 닌 비동기 경 로 를 선별 하고 비동기 경 로 를 옮 겨 다 니 며 meta.roles 와 사용자 정 보 를 비교 하여 사용자 가 접근 권한 이 있 는 지 판단 해 야 합 니 다
  •               3.최종 접근 가능 한 경 로 를 vuex 에 저장 하고 마지막 으로 router.addRoutes 를 통 해 마지막 경로 설정 목록 을 통합 합 니 다.
    token 없 음
           방문 경로 가 화이트 리스트 에 있 으 면 직접 방문 합 니 다.
           방문 경로 에 화이트 리스트 가 존재 하지 않 으 면 로그 인 페이지 path:/login?redirect=/xxx 로 다시 설정 합 니 다.로그 인 에 성공 하면/xxx 에 대응 하 는 페이지 로 이동 합 니 다.
    이상 은 Vue 루트 권한 제어 해석 의 상세 한 내용 입 니 다.Vue 루트 권한 제어 에 대한 더 많은 자 료 는 저희 의 다른 관련 글 을 주목 해 주 십시오!

    좋은 웹페이지 즐겨찾기