Vue 2.0ユーザー権限制御ソリューション
Vue-ccess-Coontrolは、Vue/Vue-Router/axiosに基づいて実現されるフロントエンドユーザ権限制御ソリューションであり、ルート、ビュー、要求の三つのレベルの制御を通じて、開発者に任意の粒子度のユーザ権限制御を実現させることができる。
インストール
バージョンの要求
Vue 2.0 x
Vue-router 3.x
取得
git:git clonehttps://github.com/tower1229/Vue-Access-Control.git
npm:npm i vue-access-control
実行
全体の考え
セッション開始時に、まず登録ルートのみのVueの例を初期化し、ルート・コンポーネントcreatedフックに登録ページにルーティングを送り、ユーザー登録成功後にフロントエンドがユーザtokenに渡され、axiosインスタンスを設定して、headersに対して「Authorzation」を追加するよう要求します。その後、経路を動的に追加し、メニューを生成し、権限命令とグローバル権限検証方法を実現し、axiosのインスタンスのために要求ブロックを追加し、これで権限制御の初期化を完了する。ルーティングを動的にロードすると、ルーティングコンポーネントはロードしてレンダリングし、フロントエンドインターフェースを表示します。
ブラウザがルートリセットを更新する問題を解決するために、tokenを取得したらsession Strageに保存します。ルートのcreatedフックは、ローカルにtokenがあるかどうかを確認します。もしあれば、登録せずに直接にtokenで権限を取得して初期化します。tokenが有効で、現在のルートがアクセスできるなら、ルートコンポーネントをロードして正確に表示します。現在のルーティングがアクセスできない場合は、ルーティング設定に従ってジャンプ404を設定する。tokenが失効すると、バックエンドは4 xx状態コードに戻り、フロントエンドはaxiosインスタンスに統一してエラーブロックを追加し、4 xx状態コードに遭遇したら終了操作を実行し、session Strageデータをクリアして登録ページにジャンプし、ユーザーに再登録させる。
最小依存原則
Vue-ccess-Coontrolの位置付けは単一の領域解決案であり、Vue/Vue-Router/axios以外の依存性はなく、理論的にはバリアフリーで任意の権限を持って必要なVueプロジェクトに適用できます。プロジェクトはwebpackテンプレート開発に基づいて構築されています。説明が必要なのは、プロジェクトに追加的に導入されたElement−UIとCryptJSは、プレゼンテーション・インターフェースの開発にのみ使用され、それらは必須ではなく、権限制御とは無関係であり、プロジェクト・アプリケーションでは自分で取捨選択することができる。
ディレクトリ構造
データ形式の約束
ルート権限データは、次のようなフォーマットのオブジェクト配列、id、parent_でなければなりません。idの同じ二つのルートは上下関係を持っています。カスタムフォーマットのルーティングデータを使用したいなら、ルーティング制御の関連実施を修正する必要があります。
ルーティング制御は、動的にルーティングを登録し、動的にメニューを生成することを含む。
動的登録ルート
最初に実装されたルーティングは、登録と404の両方の経路のみを含み、完全なルーティングが期待される。
フィルタのインプリメンテーションのアイデアは、まずバックエンドから返ってくるルーティング・データを次のようなハッシュ構造に処理することである。
バックエンドが戻ってくるルーティング権限データが約束と異なる場合、フィルタ論理は自分で実現される必要があり、実際に利用可能なルーティングデータが得られる限り、最終的にaddRoutes()の方法を使用して彼らをルーティング・インスタンスに動的に追加し、404ページの曖昧マッチングが最後に置かれることに注意する。
ダイナミックメニュー
ルートデータは直接にナビゲーションメニューを生成するために使用できますが、ルートデータはルートコンポーネントで得られます。ナビゲーションメニューはindex.vueコンポーネントに存在します。メニューデータを何らかの方法で共有する必要があることは明らかです。これはVuexの最適な使用シーンではなく、必要でない依存性をできるだけ減らすために、一番簡単な直接的な方法で、メニューデータをルートコンポーネントdata.menudataにかけて、トップページの中でthis.parent.menuDataで取得します。
また、ナビゲーションメニューにコラムアイコンを追加する必要があるかもしれません。これはルートにmetaデータを追加することによって、例えばアイコンclassやunicodeをルートmetaに保存すると、テンプレートからmetaデータにアクセスして、アイコンラベルを生成することができます。
マルチキャストシステムで出会う可能性のある問題は、同じ名前でも機能が異なるルートがあるということです。例えば、システム管理者と企業管理者には「アカウント管理」というルートがありますが、彼らの操作権限と目標は違っています。実際には2つの全く異なるインターフェースです。Vueは複数のルートが同名であることを許さないので、ルートのnameは区別しなければなりません。ただし、区別後のnameをフロントエンドメニューに表示するのは見苦しいです。異なるキャラクターが同じメニュー名を楽しめるように、この二つのルートのmeta.nameをすべて「アカウント管理」に設定して、テンプレート循環時に優先的にmeta.nameを使えばいいです。
メニューの具体的な実装はview/index.vueを参照することができます。
ビューコントロール
ビュー制御の目的は、現在のユーザ権限に基づいて、画面要素の表示の有無を決定することであり、典型的なシーンは、各種操作ボタンの表示制御である。ビューの制御を実現する本質は、権限検証方法を実現し、要求権限を入力し、出力が許可されているかどうかである。そして、v-ifやjsxやカスタムコマンドに合わせて、様々なビュー制御を柔軟に行うことができます。
グローバル検証方法
検証方法の実現自体は簡単で、バックエンドから与えられた資源の権限に基づいて判断するだけでなく、最適化方法の入出力に重点を置いて、使いやすさを向上させ、実践を通じて最終的に使用する方案は、権限と要求を同時に維持し、検証方法の受信は対象配列をパラメータとして求め、権限のあるブール値を返してください。
要求対象の書式:
権限検証方法を大域的に混入すれば、プロジェクトにおいて容易に要素表示制御を実現できるという利点は、柔軟であり、権限を検証できるほか、判断式に運行時の状態を加えてより多様性の判断を行うことができ、かつv-if応答データの変化の特徴を十分に活用して動的ビュー制御を実現することができるという点にある。
具体的な実現の詳細はVueに基づいてバックグラウンドシステムの権限制御を実現する中の関連する章節を参照します。
カスタムコマンド
v-ifの応答特性は、両刃の剣であり、判断式は実行中に頻繁にトリガされるが、実際にはユーザーセッション期間内にその権限は変化しないので、検証権限が必要であれば、v-ifで大量の不必要な演算が発生します。この場合は、ビューロード時に一度だけ確認すれば、カスタムコマンドにより実現できます。
要求コントロール
要求制御はaxiosブロッキングを利用して実現されるものであり、オフロード要求をフロントエンドでブロックすることを目的としている。原理はブロック要求において、今回の要求がユーザ権限に合致するかどうかを判断し、ブロックするかを決定することである。
一般的な要求の判断は容易で、バックエンドを巡回して戻ってくるリソース権限のフォーマットを直接判断して、request.methodとrequest.urlが合っているかどうかを判断すればいいです。パラメータ付きのurlに対してはワイルドカードを使う必要があります。ここではプロジェクトのニーズによって前後で協議して一致します。ワイルドカードのフォーマットを約束した後、ブロックの中でパラメータ付きurlを約束形式に処理してから権限を判断します。スキームでは、次の2つのワイルドカードのフォーマットが実装されています。
スクリーンショットの具体的な実現は、App.vueの中のset Interceptor()の方法を参照してください。
もしあなたのプロジェクトに他のワイルドカードのフォーマットが必要なら、ブロックの中で対応する検出と変換方法を実現すればいいです。
プレゼンテーションと説明
プレゼンテーション:
DEMOプロジェクトでは、ダイナミックメニュー、ダイナミックルーティング、ボタンの権限、傍受要求が実証されています。
デモプロジェクトのバックエンドはrap 2でmockデータを生成し、登録要求は通常POST方式であるべきですが、rap 2のプログラミングモードでは非GETの要求パラメータを取得できないため、GET方式でしか登録できません。実際のプロジェクトでは真似を勧めません。
また、ログイン後にアクセス権限を取得するインターフェースは、本来は追加のパラメータを持つ必要がなく、バックエンドは要求ヘッドによって携帯されるtoken情報によってユーザー認証を実現することができるが、rap 2のプログラミングモードではheadersデータが取得できないため、1つの「Authoriation」パラメータを追加してアナログデータを生成することができる。
テストアカウント:
インストール
バージョンの要求
Vue 2.0 x
Vue-router 3.x
取得
git:git clonehttps://github.com/tower1229/Vue-Access-Control.git
npm:npm i vue-access-control
実行
//
npm run dev
//
npm build
概要全体の考え
セッション開始時に、まず登録ルートのみのVueの例を初期化し、ルート・コンポーネントcreatedフックに登録ページにルーティングを送り、ユーザー登録成功後にフロントエンドがユーザtokenに渡され、axiosインスタンスを設定して、headersに対して「Authorzation」を追加するよう要求します。その後、経路を動的に追加し、メニューを生成し、権限命令とグローバル権限検証方法を実現し、axiosのインスタンスのために要求ブロックを追加し、これで権限制御の初期化を完了する。ルーティングを動的にロードすると、ルーティングコンポーネントはロードしてレンダリングし、フロントエンドインターフェースを表示します。
ブラウザがルートリセットを更新する問題を解決するために、tokenを取得したらsession Strageに保存します。ルートのcreatedフックは、ローカルにtokenがあるかどうかを確認します。もしあれば、登録せずに直接にtokenで権限を取得して初期化します。tokenが有効で、現在のルートがアクセスできるなら、ルートコンポーネントをロードして正確に表示します。現在のルーティングがアクセスできない場合は、ルーティング設定に従ってジャンプ404を設定する。tokenが失効すると、バックエンドは4 xx状態コードに戻り、フロントエンドはaxiosインスタンスに統一してエラーブロックを追加し、4 xx状態コードに遭遇したら終了操作を実行し、session Strageデータをクリアして登録ページにジャンプし、ユーザーに再登録させる。
最小依存原則
Vue-ccess-Coontrolの位置付けは単一の領域解決案であり、Vue/Vue-Router/axios以外の依存性はなく、理論的にはバリアフリーで任意の権限を持って必要なVueプロジェクトに適用できます。プロジェクトはwebpackテンプレート開発に基づいて構築されています。説明が必要なのは、プロジェクトに追加的に導入されたElement−UIとCryptJSは、プレゼンテーション・インターフェースの開発にのみ使用され、それらは必須ではなく、権限制御とは無関係であり、プロジェクト・アプリケーションでは自分で取捨選択することができる。
ディレクトリ構造
src/
|-- api/ //
| |-- index.js // axios
| |-- account.js // , ./index axios
|-- assets/
|-- components/
|-- router/
| |-- fullpath.js // ,
| `-- index.js //
|-- views/
|-- App.vue
・-- main.js
データ形式の約束
ルート権限データは、次のようなフォーマットのオブジェクト配列、id、parent_でなければなりません。idの同じ二つのルートは上下関係を持っています。カスタムフォーマットのルーティングデータを使用したいなら、ルーティング制御の関連実施を修正する必要があります。
[
{
"id": "1",
"name": " 1",
"parent_id": null,
"route": "route1"
},
{
"id": "2",
"name": " 1-1",
"parent_id": "1",
"route": "route2"
}
]
リソース権限データは、各オブジェクトがRESTful要求を表し、パラメータ付きurlをサポートするフォーマットのオブジェクト配列である必要があります。
[
{
"id": "2c9180895e172348015e1740805d000d",
"name": " - ",
"url": "/accounts",
"method": "GET"
},
{
"id": "2c9180895e172348015e1740c30f000e",
"name": " - ",
"url": "/account/**",
"method": "DELETE"
}
]
ルート制御ルーティング制御は、動的にルーティングを登録し、動的にメニューを生成することを含む。
動的登録ルート
最初に実装されたルーティングは、登録と404の両方の経路のみを含み、完全なルーティングが期待される。
[{
path: '/login',
name: 'login',
component: (resolve) => require(['../views/login.vue'], resolve)
}, {
path: '/404',
name: '404',
component: (resolve) => require(['../views/common/404.vue'], resolve)
}, {
path: '/',
name: ' ',
component: (resolve) => require(['../views/index.vue'], resolve),
children: [{
path: '/route1',
name: ' 1',
meta: {
icon: 'icon-channel1'
},
component: (resolve) => require(['../views/view1.vue'], resolve)
}, {
path: '/route2',
name: ' 2',
meta: {
icon: 'ico-channel2'
},
component: (resolve) => require(['../views/view2.vue'], resolve),
children: [{
path: 'child2-1',
name: ' 2-1',
meta: {
},
component: (resolve) => require(['../views/route2-1.vue'], resolve)
}]
}]
}, {
path: '*',
redirect: '/404'
}]
次にトップページとそのサブルーティングを取得する必要があります。事前にプロジェクト全体の完全なルートデータをローカルに保存し、ユーザー権限によって完全なルートをフィルタリングします。フィルタのインプリメンテーションのアイデアは、まずバックエンドから返ってくるルーティング・データを次のようなハッシュ構造に処理することである。
let hashMenus = {
"/route1":true,
"/route1/route1-1":true,
"/route1/route1-2":true,
"/route2":true,
...
}
その後、ローカルの完全なルートを巡回して、経路を上記の構造のkeyフォーマットにつづり合わせ、hashMenus[route]を通じてルートがマッチングするかどうかを判断できます。具体的には、App.vueファイルのget Routesを参照してください。バックエンドが戻ってくるルーティング権限データが約束と異なる場合、フィルタ論理は自分で実現される必要があり、実際に利用可能なルーティングデータが得られる限り、最終的にaddRoutes()の方法を使用して彼らをルーティング・インスタンスに動的に追加し、404ページの曖昧マッチングが最後に置かれることに注意する。
ダイナミックメニュー
ルートデータは直接にナビゲーションメニューを生成するために使用できますが、ルートデータはルートコンポーネントで得られます。ナビゲーションメニューはindex.vueコンポーネントに存在します。メニューデータを何らかの方法で共有する必要があることは明らかです。これはVuexの最適な使用シーンではなく、必要でない依存性をできるだけ減らすために、一番簡単な直接的な方法で、メニューデータをルートコンポーネントdata.menudataにかけて、トップページの中でthis.parent.menuDataで取得します。
また、ナビゲーションメニューにコラムアイコンを追加する必要があるかもしれません。これはルートにmetaデータを追加することによって、例えばアイコンclassやunicodeをルートmetaに保存すると、テンプレートからmetaデータにアクセスして、アイコンラベルを生成することができます。
マルチキャストシステムで出会う可能性のある問題は、同じ名前でも機能が異なるルートがあるということです。例えば、システム管理者と企業管理者には「アカウント管理」というルートがありますが、彼らの操作権限と目標は違っています。実際には2つの全く異なるインターフェースです。Vueは複数のルートが同名であることを許さないので、ルートのnameは区別しなければなりません。ただし、区別後のnameをフロントエンドメニューに表示するのは見苦しいです。異なるキャラクターが同じメニュー名を楽しめるように、この二つのルートのmeta.nameをすべて「アカウント管理」に設定して、テンプレート循環時に優先的にmeta.nameを使えばいいです。
メニューの具体的な実装はview/index.vueを参照することができます。
ビューコントロール
ビュー制御の目的は、現在のユーザ権限に基づいて、画面要素の表示の有無を決定することであり、典型的なシーンは、各種操作ボタンの表示制御である。ビューの制御を実現する本質は、権限検証方法を実現し、要求権限を入力し、出力が許可されているかどうかである。そして、v-ifやjsxやカスタムコマンドに合わせて、様々なビュー制御を柔軟に行うことができます。
グローバル検証方法
検証方法の実現自体は簡単で、バックエンドから与えられた資源の権限に基づいて判断するだけでなく、最適化方法の入出力に重点を置いて、使いやすさを向上させ、実践を通じて最終的に使用する方案は、権限と要求を同時に維持し、検証方法の受信は対象配列をパラメータとして求め、権限のあるブール値を返してください。
要求対象の書式:
//
const request = {
p: ['get,/accounts'],
r: params => {
return instance.get(`/accounts`, {params})
}
}
権限検証方法has()の呼び出しフォーマット:
v-if="$_has([request])"
権限検証方法の具体的な実現は、App.vueの中でVue.prototypeを参照してください。hasの方法。権限検証方法を大域的に混入すれば、プロジェクトにおいて容易に要素表示制御を実現できるという利点は、柔軟であり、権限を検証できるほか、判断式に運行時の状態を加えてより多様性の判断を行うことができ、かつv-if応答データの変化の特徴を十分に活用して動的ビュー制御を実現することができるという点にある。
具体的な実現の詳細はVueに基づいてバックグラウンドシステムの権限制御を実現する中の関連する章節を参照します。
カスタムコマンド
v-ifの応答特性は、両刃の剣であり、判断式は実行中に頻繁にトリガされるが、実際にはユーザーセッション期間内にその権限は変化しないので、検証権限が必要であれば、v-ifで大量の不必要な演算が発生します。この場合は、ビューロード時に一度だけ確認すれば、カスタムコマンドにより実現できます。
//
Vue.directive('has', {
bind: function(el, binding) {
if (!Vue.prototype.$_has(binding.value)) {
el.parentNode.removeChild(el);
}
}
});
カスタムコマンドの内部では依然としてグローバル認証方法を起動していますが、要素初期化時に一回だけ実行されるのが利点です。多くの場合、カスタムコマンドを使用してビュー制御を実現するべきです。要求コントロール
要求制御はaxiosブロッキングを利用して実現されるものであり、オフロード要求をフロントエンドでブロックすることを目的としている。原理はブロック要求において、今回の要求がユーザ権限に合致するかどうかを判断し、ブロックするかを決定することである。
一般的な要求の判断は容易で、バックエンドを巡回して戻ってくるリソース権限のフォーマットを直接判断して、request.methodとrequest.urlが合っているかどうかを判断すればいいです。パラメータ付きのurlに対してはワイルドカードを使う必要があります。ここではプロジェクトのニーズによって前後で協議して一致します。ワイルドカードのフォーマットを約束した後、ブロックの中でパラメータ付きurlを約束形式に処理してから権限を判断します。スキームでは、次の2つのワイルドカードのフォーマットが実装されています。
1. :/resources/:id
:/resources/1
url: /resources/**
: , id
2. :/store/:id/member
:/store/1/member
url:/store/*/member
: , id
最初のフォーマットで注意が必要なのは、urlが「/aa/bb」であるという要求を開始する場合、デフォルトは「/aa/**」として処理されます。ここの「bb」がパラメータではなくurlの一部である場合、urlを「/aa/bb/」に変更し、最後に「url」を加えます。スクリーンショットの具体的な実現は、App.vueの中のset Interceptor()の方法を参照してください。
もしあなたのプロジェクトに他のワイルドカードのフォーマットが必要なら、ブロックの中で対応する検出と変換方法を実現すればいいです。
プレゼンテーションと説明
プレゼンテーション:
DEMOプロジェクトでは、ダイナミックメニュー、ダイナミックルーティング、ボタンの権限、傍受要求が実証されています。
デモプロジェクトのバックエンドはrap 2でmockデータを生成し、登録要求は通常POST方式であるべきですが、rap 2のプログラミングモードでは非GETの要求パラメータを取得できないため、GET方式でしか登録できません。実際のプロジェクトでは真似を勧めません。
また、ログイン後にアクセス権限を取得するインターフェースは、本来は追加のパラメータを持つ必要がなく、バックエンドは要求ヘッドによって携帯されるtoken情報によってユーザー認証を実現することができるが、rap 2のプログラミングモードではheadersデータが取得できないため、1つの「Authoriation」パラメータを追加してアナログデータを生成することができる。
テストアカウント:
1. username: root
password:
2. username: client
password: