vue管理システム権限制御モジュール

4653 ワード

ビジネスの背景
バックエンド管理システムの開発のポイントは、権限制御とセキュリティです.
すべてはログインから
ユーザーが管理システムに入ってアカウントとパスワードを入力し、バックエンドに送信してアカウントとパスワードの正確性の検証を行い、アカウントとパスワードが正しい場合、バックエンドはそのユーザーに属する唯一のtokenを返します.この時、私たちがしなければならないのはtokenを保存し、cookie、session、localStorage、vuexに保存して自分のニーズを見ることです.ここではプロジェクトの要求に応じてvuexに保存します.vuexはsessionStorageと協力して、ページのリフレッシュをvuexのデータを失わないようにしています.
tokenを使用してユーザー情報を交換する
バックエンドの設計は一般的にtokenがあった後、取得ユーザー情報インタフェースを呼び出してログイン者の関連情報を取得します.例えば、ログイン名、顔、バックエンド管理システム、権限情報リストなどです.これは後で権限制御を行う主な根拠です.
開始権限制御-vue-routerのナビゲーションガード
  • 案一:
  • 権限リストを取得した後、対応する権限のルーティング構成ルーティングテーブルを算出しrouterを使用する.addRoutes()ダイナミックマウントルーティング、セルフパンツ参照https://juejin.im/post/591aa14f570c35006961acac
    このスキームを用いることによる問題は、ユーザがブラウザをリフレッシュし、vuexに保存するとsessionStorageやlocalStorageに保存しても失効することである.失効原因は、ユーザがページをリフレッシュするときにvueがプログラム全体をロードし、mainを再実行したためである.jsはこれでrouterも初期化され、権限を必要としないページルーティングに初期化されますが、mainでもいいです.jsは再び権限を必要とするルートを検出して、再びaddRoutersを使って動的ルートを追加して、しかし1つのルートの命名の繰り返しの警告を報告して、しかし私のコードの論理は問題があって、このバグは私が解決できないで会社の大物を探して、大物は私に方案の2の構想をあげます
  • 案二
  • 直接ルーティングプロファイルの時にすべての権限が必要なページをルーティングmeta属性で書き、main.jsロード時に改ページにアクセスする権限があるかどうかを判断し、addRouterを使用して動的に追加しないことで、ユーザーがページをリフレッシュしても、routerが初期化したときにすべてのルーティングを初期化することができることを保証することができます.私たちはナビゲーションガードのリターン関数の中で権限の鑑定を行うだけでいいです.そして、このガード権限の鑑定はグローバルで、ルーティングの変化があれば、権限認証が行われます
    main.jsファイル
    import Vue from 'vue'
    import App from './App.vue'
    import router from './router'
    import store from './vuex/store'
    import '@/reqConfig/index.js'
    import token from '@/reqConfig/token.js'
    import ElementUI from 'element-ui'
    import 'element-ui/lib/theme-chalk/index.css'
    import '@/assets/reset.css'
    
    Vue.use(ElementUI)
    
    Vue.config.productionTip = false
    
    // [skip       ]
    function skip () {
      //       session token
      sessionStorage.clear()
      token.clearToken()
      window.location.href = process.env.VUE_APP_LOGOUT_URL
    }
    
    //         
    router.beforeEach((to, from, next) => {
      let userInfo = store.state.userinfo.userInfo
      if (userInfo) {
        if (userInfo.account_available) {
          let roles = userInfo.permissions
          //               
          if (to.meta.role) {
            let isHasPermission = to.meta.role.every(item => {
              return roles.includes(item)
            })
            if (isHasPermission) {
              next()
            } else {
              ElementUI.Message.error('         ,        ')
            }
          } else {
            next()
          }
        } else {
          ElementUI.Message({
            type: 'error',
            message: '         ,        ',
            onClose: function () {
              skip()
            }
          })
        }
      } else {
        let key = sessionStorage.getItem('sso-token')
        if (!key) {
          skip()
        } else {
          store.dispatch('getXStreamId').then(() => {
            store.dispatch('getUserInfo').then(res => {
              userInfo = store.state.userinfo.userInfo
              if (userInfo.account_available) {
                let roles = userInfo.permissions
                //               
                if (to.meta.role) {
                  let isHasPermission = to.meta.role.every(item => {
                    return roles.includes(item)
                  })
                  if (isHasPermission) {
                    next()
                  } else {
                    ElementUI.Message.error('         ,        ')
                  }
                } else {
                  next()
                }
              } else {
                ElementUI.Message({
                  type: 'error',
                  message: '         ,        ',
                  onClose: function () {
                    skip()
                  }
                })
              }
            })
          }).catch(() => {
            skip()
          })
        }
      }
    })
    
    new Vue({
      router,
      store,
      render: h => h(App)
    }).$mount('#app')
    

    ルーティングプロファイル
    import Vue from 'vue'
    import Router from 'vue-router'
    import A from '@/views/A.vue'
    import B from '@/views/B.vue'
    import C from '@/views/C.vue'
    import D from '@/views/D.vue'
    
    Vue.use(Router)
    
    export const routerMap = [
      {
        path: '/',
        name: 'A',
        component: A
      },
      {
        path: '/b',
        name: 'B',
        component: B,
        meta: { role: ['      ,     admin    '] }
      },
      {
        path: '/c',
        name: 'C',
        component: C,
        meta: { role: [      ,     super admin    ] }
      },
      {
        path: '/d',
        name: 'D',
        component: D,
        meta: { role: [      ,     boss    ] }
      }
    ]
    
    export default new Router({
      routes: routerMap
    })