vue項目後臺權限驗證+axios封裝

項目網址: https://gitee.com/vueGitee/vueGitee/tree/master/loginCheck前端

思路:1: 登陸: 用戶輸入帳號密碼,向服務器驗證是否正確,驗證經過,服務器返回一個token(惟一標示用戶身份的一個key),前端將token存儲於 cookie,vuex UserToken 變量中,路由重定向到 path:'/'vue

   2:權限驗證: main.js 裏面添加路由導航守衛ios

    2.1:  beforeEach 控制路由跳轉:UserToken有值的話,判斷 vuex/permission 裏面的變量permissionList  是否有值,git

      沒值的話,根據token,調用接口獲取用戶對應權限,前端會有一份路由表(src/router/dynamic-router.js),它表示了每個路由可訪問的權限 ,動態根據用戶的 role 算出其對應有權限的路由,addRoute() 添加路由,並循環顯示主頁面左邊側邊欄的標題,vuex

    2.2:  afterEach:經過vuex,設置主頁面右邊頭部的麪包導航, 左邊標題欄的選中項axios

注意事項: 1: UserToken 存儲在cookie中,前端設置cookie有效期  ((本項目未實現 :) 後臺那邊設置 UserToken 的有效期,每次請求接口,都帶上token(即axios 封裝 請求頭裏面  config.headers.Authorization = store.state.UserTokenapi

),根據後臺返回的狀態碼,前端作出相應處理。如 res.code === 10001 ,表示token失效,toast 提醒,再退出登陸; res.code === 10002,表示網絡異常,前端toast 提醒; 若沒有相應權限.....)瀏覽器

步驟緩存

1:vuex 聲明變量 (文件路徑:src/store/state.js)服務器

import {setCookie, getCookie} from '../utils/cookie'

export default {
  get UserToken () { // 判斷用戶是否登陸
    // return localStorage.getItem('token')
    // return cookies.get('token')
    return getCookie('token')
  },
  set UserToken (value) {
    setCookie('token', value, 10)
    console.log('getCookie(token)', getCookie('token'))
    // return localStorage.setItem('token', value)
    // return cookies.set('token', value)
  },
  // 導航菜單是否摺疊
  isSidebarNavCollapse: false,
  // 麪包屑導航列表
  crumbList: []
}

2: 登陸頁面,點擊‘登陸’按鈕,調用 login 函數,調用後臺接口,前端把接口返回數據中的token變量放到 vuex UserToken,而且放在cookie 裏面(防止用戶刷新瀏覽器頁面,vuex 裏面的state恢復初始值 ),設置路由重定向到  ‘/’  

 async login () {
      // 此時爲異步函數
      try {
        let data = await login() // await 同步 等待 須要的等到 await 後面的函數執行完之後有了返回結果,才能執行下面的代碼
        let token = data.token
        this.$store.commit('LOGIN_IN', token)
        this.$router.replace('/')
      } catch (e) {
        console.log(e)
      }
    }
src/store/mutations.js
 LOGIN_IN (state, token) {
    // 這步操做,實現了state 中的 UserToken 賦值, 同時執行 set UserToken (value) 方法,把token 值放到了 sessionStorage(或cookie) 裏面
    // 由於刷新頁面,vuex 變量 中的值 變成默認值 '' ,因此放到本地緩存裏面,刷新頁面之後,調用 get UserToken () 方法  從本地緩存中獲取token取值
    state.UserToken = token
  },
src/store/state.js
get UserToken () { // 判斷用戶是否登陸
    // return localStorage.getItem('token')
    return getCookie('token')
  },
  set UserToken (value) {
    setCookie('token', value, 10) // cookie 有效期設置爲 10s
    console.log('getCookie(token)', getCookie('token'))
    // return localStorage.setItem('token', value)
  },

3:main.js 添加 路由鉤子函數

router.beforeEach((to, from, next) => {
  if (!store.state.UserToken) {
    // some 方法 判斷 即將被打開的路由裏面,是否有 requiresAuth 屬性 ,以此來判斷是否驗證,但凡是有一個取值爲true,則去登陸頁面,去登陸驗證
    if (to.matched.length > 0 && !to.matched.some(record => {
      return record.meta.requiresAuth
    })) {
      next()
    } else {
      next({path: '/login'})
    }
  } else {
    if (!store.state.permission.permissionList) { //  (!null === true)  取值爲空,說明路由尚未動態建立
      store.dispatch('permission/FETCH_PERMISSION').then(() => {
        next({path: to.path})
      })
    } else {
      if (to.path !== '/login') {
        next()
      } else {
        next(from.fullPath)
      }
    }
  }
})

沒有UserToken , 不須要驗證的話,直接 next(), 須要驗證的話,跳登陸頁面

有UserToken(已登陸),permissionList 不存在 ,調用 actions 裏面的 FETCH_PERMISSION 方法,去生成動態路由。

4: FETCH_PERMISSION  方法  

 state: {
    // 全部路由
    permissionList: null,
    // 導航菜單
    slidebarMenu: [],
    // 當前 active 導航菜單
    currentMenu: ''
  },
async FETCH_PERMISSION ({commit, state}) {
      let permissionList = await fetchPermission()
      let routes = recursionRouter(permissionList, dynamicRouter)
      console.log('routes', routes)
      let mainContainer = DynamicRoutes.find(v => v.path === '')
      let children = mainContainer.children
      children.push(...routes)
      commit('SET_MENU', children) // 生成側邊欄
      setDefaultRoute([mainContainer])
      //   初始化路由
      let initialRoutes = router.options.routes
      router.addRoutes(DynamicRoutes)  // 生成完成路由表
      commit('SET_PERMISSION', [...initialRoutes, ...DynamicRoutes])  //permissionList變量 表示完整的路由,在main.js  router.beforeEach鉤子函數中,調用了它
}

5: 路由 router/index.js: 路由一開始只有 /login 

// 初始化路由
export default new Router({
  routes: [
    {
      path: '/login',
      component: Login
    }
  ]
})

 

// 準備動態添加路由
export const DynamicRoutes = [
  {
    path: '',
    component: Layout,
    name: 'container',
    redirect: 'home',
    meta: {
      requiresAuth: true,
      name: '首頁'
    },
    children: [
      {
        path: 'home',
        component: Home,
        name: 'home',
        meta: {
          name: '首頁',
          icon: 'icon-home'
        }
      }
    ]
  },
  {
    path: '/403',
    component: Forbidden
  },
  {
    path: '*',
    component: NotFound
  }
]

登陸之後,頁面重定向到 path: '/'   即 path: '', 此時又重定向到子路由    path: 'home', 由於是子路由,因此頁面顯示是 父路由 (父組件:Layout)+ 子路由(子組件:Home),最終子組件在 

src/pages/layout/component/main-content/content.vue  顯示出來
content.vue 代碼以下:
<router-view class="content"></router-view>

  axios 封裝在   src/config/httpConfig.js 中      src/api/permission.js中根據不一樣的接口url,生成不一樣的接口請求方法

相關文章
相關標籤/搜索