目次
2 動的ルーティング テーブルを取得するための許可データ フィルタリングの取得
3 動的ルーティング テーブルがルーターをロードし、左側のメニューをレンダリングします
正面
ユーザーへのロールの割り当てとロールへのアクセス許可の割り当ての基本的な前提条件を完了する必要があり、バックエンド/モックからユーザーのアクセス許可情報を取得できます。
RBAC パーミッション デザイン アイデアとは
簡単に言えば、あなたがプロのチェス プレーヤー (役割) であれば、中国のチェス アカデミー(権限) に入ることができます。部外者が入ることを許可しません、彼は入ることができません (許可)
ある日、あなたの友人は発狂し、24 時間残業し、プロ棋士の資格 (役割) を取得し、中国のチェス アカデミーに入学できるようになりました (許可)。
要するに、従業員に1つずつ権限を付与するのは面倒なのでしょうか? 会社にはルールがあり、役割aにはタイプaの権限があり、役割bにはbの権限があることが多く、新しい従業員に権限を直接追加したい上司によると 彼に役割を与えてください
役割は権限の集合です
ページ レベルのパーミッションの実装プロセス
分析する
まずはルーティングガードで、ログイン後トークンがあり、elseを入力してvuexアクションを投入し、非同期でuserInfoを取得、vuexの戻り値にパーミッションデータが含まれる
1 ルーティングルーター/index.jsの設定
まず、ページオーソリティはルーティングルーターに関係し、ルーティングテーブルは対応するページコンポーネントにジャンプできるかどうかを制御する鍵であることを知っています. したがって、これらの8つの動的ルートに従って、動的に設定する必要があります.メニュー設定
ルーター/index.js
ご覧のとおり、ここでは無効に記述しているため、各ユーザーはすべてのページにアクセスできます。ここでは、直接削除します... asyncRoutes
2 動的ルーティング テーブルを取得するための許可データ フィルタリングの取得
次に、バックエンドから返されたメニューと動的ルーティング テーブルとの間の接続を確立する必要があります. menus を最初に取得する場所について考えてみてください.そして、dispatch は promise オブジェクトを返すので、ルート ガードでこの値を待つことができます。
拡張機能: The return promise object in vuex official website => actions has the required value. You can directly return the required value here . vuex 公式サイトにそう書いてあるので首先,你需要明白 store.dispatch 可以处理被触发的 action 的处理函数返回的 Promise,并且 store.dispatch 仍旧返回 Promise:
vex の戻り値
ルーティング ガードの値を取得する
Print はルーティング ガードで最も早いメニューを取得できます
ここで次に行う必要があるのは、作成された動的ルーティング テーブルを取得し、メニューに従ってフィルター処理して、新しいルーティング テーブルを取得することです。
私の各ダイナミックルーティングオブジェクトはこんな感じです.path属性を使って2桁以降の文字列をフィルタリングしたり、名前を直接使ったりできることがわかります.パスを使って判断しています.
ルートガード
const { menus } = await store.dispatch('user/getInfo')
const filterAsyncRoutes = asyncRoutes.filter(item => menus.includes(item.path.slice(1)))
フィルタリング権限取得後のダイナミックルーティングテーブル
3 動的ルーティング テーブルがルーターをロードし、左側のメニューをレンダリングします
ルーティング ガードで新しい動的ルーティング テーブルが取得されました。次に行うことは 2 つあります。
- ルーターにロード
- 動的ルーティングと静的ルーティングを接合し、左側のメニューをレンダリングする
左側のメニューは他のコンポーネントであり、ルーティング テーブルに従ってレンダリングされ、コンポーネント間で使用できるため、vuex を使用して動的および静的ルートをここに保存し、それらをルーターにロードします。具体的な方法は次のとおりです。上記のルーティング ガードが必要なデータ ミューテーションを取得した直後に送信するには、静的ルーティング テーブルが vuex にインポートされ、静的およびフィルタリングされた動的ルーティング テーブルがミューテーションで接合され、最終的な totalRoutes が生成されます
ルート ガードが上記の値を取得したら、すぐに動的ルートをルーターにロードします。
const { menus } = await store.dispatch('user/getInfo')
const filterAsyncRoutes = asyncRoutes.filter(item => menus.includes(item.path.slice(1)))
router.addRoutes(filterAsyncRoutes)
store.commit('menu/loadRoute', filterAsyncRoutes)
vuex コード ルーティング ガードはミューテーションを送信し、フィルタリングされた動的ルーティング テーブルを静的ルーティング テーブルに渡し、最終的なルーティング テーブルを合成して左側のメニューをレンダリングします。
左側のメニュー ロジックを分析する
siderbar コンポーネントの index.vue
本来、this.$router.options.routes は router/index.js で設定したルーティング テーブルであり、動的に追加したルーティング テーブルは自動的にルーティング テーブルに更新されるわけではなく、this.$router.options.routes です。初期化中に構成されたルーティング ルールを取得するため、自分で vuex に保存したいのですが、これも意図的に Vue で設計されています。options is the object passed to the vuerouter constructor. It's not modified afterwards.
ただし、著者は上記の方法を使用することをお勧めしません。vuex に保存することをお勧めします。
次に、左側のメニュー設定変更コードは、動的に設定されたルーティング テーブルを vex から取得します。
左側のメニューがレンダリングされます
4つのバグが解決されました
バグ 1: 更新 404
上記の部門組織構造などの動的ルーティングページでは、通常はアクセスできますが、更新する限り、404 問題が見つかります。
静的ルーティング テーブルの最後のルールは *wildcard to 404 であるため、更新時に動的ルーティングをルーティング インスタンスに再マウントする必要がありますが、マウントされる前に 404 ページへのワイルドカードによってインターセプトされます。
解決策: 404 は静的ルーティング テーブルから削除され、フィルタリングされた動的ルーティング テーブルの最後に追加されます。つまり、404 ルールにプッシュされます。
バグ 2: 空白を更新/ページがエラーなしで読み込まれない
ねえ、バグ 1 は解決されました。別のバグを見つけましたか? ページを更新しても読み込まれず、エラーが報告されず、空白です
これはなぜでしょうか? 初めて遭遇したときは疑問に思ったのですが、後で情報を調べたところ、おそらくガードにRoutesを追加し、実行が完了する前にnext()を実行したため、 next (to.path) もう一度ガードに入り、この時点で動的ルートが追加されました
バグ 3: ログアウトして再度ログインすると、コンソールはルート情報を繰り返し追加し、許可のないアカウントがページを更新しない限り、アドレス バーからアドレスを入力して、許可なく元のアドレスにアクセスできます。
ログアウト時にルートを再設定していないため、ここで最も深刻なのはパーミッションの混乱です。以前のユーザーの動的ルーティング情報がクリアされていないため、パーミッション リークが発生するため、ログアウト時にルートを再設定します
一般的に、設定する必要がある場所は 3 つあります。
// router/index.js 定义重置路由方法
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
// vuex登出actions中 最后重置路由
// 以及一切你知道的问题处 比如token失效时一般我们放到request拦截器里面处理
import { resetRouter } from '@/router'
logout(context) {
context.commit('updateToken', '')
context.commit('setUserInfo', {})
resetRouter()
}
// 我的拦截器中设置当401 status时 提交actions 登出 所以我只用设置上面vuex那段
// 响应拦截器
async error => {
// console.log('响应拦截器error')
if (error.response.status === 401) {
await store.dispatch('user/logout')
router.push(`/login?redirect=${router.currentRoute.fullPath}`)
}
Message.error(error.response.data.message)
return Promise.reject(error)
}
Bug4: ログアウトしたか、トークンが期限切れになったため、元の Web ページのアドレスのパス情報がアドレス バーに自動的に追加されます. ログアウトして、元の Web ページの権限を持たないユーザーでログインすると、 next(to.path)に404が表示される 判定を追加、メニューにない場合は直接ホームページへジャンプ
menus.includes(to.path.substring(1)) ? next(to.path) : next('/')
menus: バックエンドから返されるパーミッション配列要素はページ ID です
この時点で、基本的にページの権限管理は基本的に行われていますが、浪費を学びましたか...