Vue2.0でのユーザー権限の操作方法

php中世界最好的语言
リリース: 2018-04-14 13:54:29
オリジナル
1422 人が閲覧しました

今回は、Vue2.0でユーザー権限を操作する方法と、Vue2.0でユーザー権限を操作する際の注意点を紹介します。実際のケースを見てみましょう。

Vue-Access-Control は、Vue/Vue-Router/axios に基づくフロントエンドのユーザー権限制御ソリューションであり、ルーティング、ビュー、リクエストの制御を通じて、開発者はあらゆる粒度のユーザー権限制御を実現できます。

インストール

バージョン要件

Vue 2.0x
Vue-router 3.x
Get

git: git clone https://github.com/tower1229/Vue-Access-Control.git

npm: npm i vue-access-control

走る

りー

概要

全体的なアイデア

セッションの開始時に、まずログイン ルーティングのみを使用して Vue インスタンスを初期化し、ルート コンポーネントの作成されたフックでログイン ページにルーティングを指示します。ユーザーが正常にログインした後、フロントエンドはユーザー トークンを取得し、 axios インスタンスを使用して、リクエスト ヘッダーに一律に {" を追加します。 Authorization":token} はユーザー認証を実装し、主にルーティング パーミッションとリソース パーミッションを含む現在のユーザーのパーミッション データを取得します。その後、ルートを動的に追加し、メニューを生成し、パーミッションの指示を実装します。およびグローバル権限検証メソッドを追加し、axios デバイスのリクエスト インターセプトを追加すると、権限制御の初期化が完了します。ルートを動的にロードした後、ルーティング コンポーネントがロードされてレンダリングされ、フロントエンド インターフェイスが表示されます。 ブラウザ更新ルートのリセットの問題を解決するには、トークンを取得した後、作成されたルート コンポーネントのフックがトークンがローカルに存在するかどうかを確認する必要があります。ログインしてトークンを直接使用して権限を取得し、トークンを初期化します。トークンが有効で、現在のルートにアクセス権がある場合、ルーティング コンポーネントは正しく読み込まれて表示されます。現在のルートにアクセス権がない場合は、ジャンプします。ルーティング設定に従って 404 に変換されます。トークンが無効な場合、バックエンドは 4xx ステータス コードを返す必要があり、フロントエンドは 4xx ステータス コードに遭遇すると、一律にエラーを axios インスタンスに追加し、終了操作を実行し、sessionStorage データをクリアします。ログイン ページにジャンプすると、ユーザーは再度ログインできるようになります。

依存度を最小限にする原則

Vue-Access-Control は単一ドメイン ソリューションとして位置付けられており、Vue/Vue-Router/axios 以外の依存関係はありません。このプロジェクトは、権限制御要件を持つすべての Vue プロジェクトに適用できます。ウェブパック テンプレート開発ビルドでは、ほとんどの新しいプロジェクトは、チェックアウトされたコードに基づいて直接開発できます。プロジェクトで導入された追加の Element-UI と CryptoJS は、デモ インターフェイスの開発にのみ使用されるため、必要なく、プロジェクト アプリケーションで自分で選択できます。

ディレクトリ構造

データ形式の規約

ルーティング許可データは、次の形式のオブジェクト配列である必要があります。同じ id とparent_id を持つ 2 つのルートには上位と下位の関係があります。カスタム形式のルーティング データを使用する場合は、関連するルーティング制御の実装を変更する必要があります。 。

りー

リソース許可データは、次の形式のオブジェクト配列である必要があります。各オブジェクトは RESTful リクエストを表し、パラメーター付きの URL をサポートします。

りー

ルーティング制御

ルーティング制御には、ルートの動的登録とメニューの動的生成の 2 つの部分が含まれます。

動的登録ルート

最初にインスタンス化されたルートには、ログインと 404 の 2 つのパスのみが含まれています。完全なルートは次のようになると予想されます:

src/
 |-- api/     //接口文件
 |  |-- index.js    //输出通用axios实例
 |  |-- account.js   //按业务模块组织的接口文件,所有接口都引用./index提供的axios实例
 |-- assets/
 |-- components/
 |-- router/
 |  |-- fullpath.js   //完整路由数据,用于匹配用户的路由权限得到实际路由
 |  `-- index.js   //输出基础路由实例
 |-- views/
 |-- App.vue
 ·-- main.js
ログイン後にコピー

次に、ホームページとそのサブルートを取得する必要があります。これは、プロジェクト全体の完全なルーティング データを事前にローカルに保存し、ユーザーの権限に基づいて完全なルートをフィルタリングすることです。

フィルタリングの実装の考え方は、まずバックエンドから返されたルーティング データを次のハッシュ構造に処理することです:

[
 {
  "id": "1",
  "name": "菜单1",
  "parent_id": null,
  "route": "route1"
 },
 {
  "id": "2",
  "name": "菜单1-1",
  "parent_id": "1",
  "route": "route2"
 }
 ]
ログイン後にコピー

次に、ローカルの完全なルートを走査し、ループ内の上記の構造のキー形式にパスを結合します。具体的な実装については、アプリの getRoutes() メソッドを参照してください。 vueファイル。

バックエンドから返されたルーティング権限データが契約と異なる場合は、実際に利用可能なルーティング データを取得できる限り、最終的に addRoutes() メソッドを使用して動的に追加することができます。フィルタリング ロジックを自分で実装する必要があります。ルーティング インスタンスは、404 ページのあいまいさに注意してください。一致は最後に配置する必要があります。

ダイナミックメニュー

路由数据可以直接用来生成导航菜单,但路由数据是在根组件中得到的,导航菜单存在于index.vue组件中,显然我们需要通过某种方式共享菜单数据,方法有很多,一般来说首先想到的是Vuex,但菜单数据在整个用户会话过程中不会发生改变,这并不是Vuex的最佳使用场景,而且为了尽量减少不必要的依赖,这里用了最简单直接的方法,把菜单数据挂在根组件data.menuData上,在首页里用this.$parent.menuData获取。

另外,导航菜单很可能会有添加栏目图标的需求,这可以通过在路由中添加meta数据实现,例如将图标class或unicode存到路由meta里,模板中就可以访问到meta数据,用来生成图标标签。

在多角色系统中可能遇到的一个问题是,不同角色有一个名字相同但功能不同的路由,比如说系统管理员和企业管理员都有”账号管理”这个路由,但他们的操作权限和目标不同,实际上是两个完全不同的界面,而Vue不允许多个路由同名,因此路由的name必须做区分,但把区分后的name显示在前端菜单上会很不美观,为了让不同角色可以享有同一个菜单名称,我们只要将这两个路由的meta.name都设置成”账号管理”,在模板循环时优先使用meta.name就可以了。

菜单的具体实现可以参考views/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实现元素显示控制,这种方式的优点在于灵活,除了可以校验权限外,还可以在判断表达式中加入运行时状态做更多样性的判断,而且可以充分利用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处理成约定格式,再判断权限,方案中已经实现了以下两种通配符格式:

1. 格式:/resources/:id
 示例:/resources/1
 url: /resources/**
 解释:一个名词后跟一个参数,参数通常表示名词的id
 
2. 格式:/store/:id/member
 示例:/store/1/member
 url:/store/*/member
 解释:两个名词之间夹带一个参数,参数通常表示第一个名词的id
ログイン後にコピー

对于第一种格式需要注意的是,如果你要发起一个url为"/aaa/bbb"的请求,默认会被处理成"/aaa/**"进行权限校验,如果这里的”bbb”并不是参数而是url的一部分,那么你需要将url改成"/aaa/bbb/",在最后加一个”/“表示该url不需要转化格式。

インターセプターの具体的な実装については、App.vue の setInterceptor() メソッドを参照してください。

プロジェクトで他のワイルドカード形式が必要な場合は、対応する検出メソッドと変換メソッドをインターセプターに実装するだけで済みます。

デモンストレーションと説明

デモの説明:

DEMO プロジェクトでは、動的メニュー、動的ルーティング、ボタンのアクセス許可、およびリクエストのインターセプトを示します。

デモプロジェクトのバックエンドはrap2でモックデータを生成しますが、通常はログインリクエストはPOSTメソッドで行う必要がありますが、rap2のプログラミングモードではGET以外のリクエストパラメータを取得できないため、GETメソッドでしかログインできません。実際のプロジェクトでこの例に従うことはお勧めしません

。 さらに、ログイン後に権限を取得するためのインターフェイスでは、追加のパラメーターを運ぶ必要はありません。ただし、rap2 のプログラミング モードではヘッダー データを取得できないため、バックエンドはリクエスト ヘッダーに含まれるトークン情報に基づいてユーザー認証を実装できます。 「認可」パラメータのみを追加できます。シミュレーション データの生成に使用されます。

この記事の事例を読んだ後は、この方法を習得したと思います。さらに興味深い情報については、php 中国語 Web サイトの他の関連記事に注目してください。

推奨読書:

node.jsはマルチユーザーWebターミナル操作を実装します

WeChatアプレットにポップアップダイアログボックスを追加します

以上がVue2.0でのユーザー権限の操作方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!