Vue要素のバックグラウンド認証プロセスの分析

Vue要素のバックグラウンド認証プロセスの分析

序文:

最近、プロジェクトで管理システムに遭遇しました。権限設定が非常に興味深いと思いました。自分の学習を容易にし、考えを整理するために、プロセスの実装プロセスを記録しました。考えの一部は、コードのコメントに統合されています。

ルーティング傍受認証の2つの一般的な方法

1: ルートインターセプション: ルートにフィールド識別子を追加し、ルートインターセプションを通じて実装するだけです
2: 動的ルーティング: 2 番目のタイプは、ルーティング分割を通じて実装され、バックエンドの協力を必要とする動的ルーティング構成です。

比較する:

ルートインターセプションの実装は比較的簡単です。router.beforeEach 内のページをルート設定情報に従ってフィルタリングし、コンポーネントに移動する権限があるかどうかを確認するだけです。対応する権限が不十分な場合は、対応するコンポーネントに移動しません。

動的ルーティングは実装が比較的複雑で、バックエンドの協力が必要です。本質的には、ルーティング構成テーブルは 2 つの部分に分かれています。異なるユーザーがログインすると、ルーティング構成テーブルはユーザーの権限情報に基づいてフィルタリングされ、ユーザーが追加する権限を持たない部分はレンダリングされません。比較的大規模なバックエンド システムに適しています。

注: この記事では主に動的ルーティング認証の実装について紹介します

次のファイルは通常、動的ルーティングに関連しています。

  • ルータ
  • permission.js (グローバルルーティングインターセプションファイル)
  • ストア

ルータ

router.js のルーティング設定テーブルは、パブリックルーティングと動的パーミッションルーティングの 2 つの部分に分けられます。動的パーミッションルーティングはフロントエンドに配置できます。認証時に、フロントエンドが配列を独自にフィルタリングすることも、バックエンドに配置してフィルタリングすることもできます。考え方は同じです。以下では、フロントエンドに配置される設定テーブルについて説明します。

デフォルトの新しいルーターをエクスポートします({ 
ルート:
   {
		パス:'/login',
		名前:'ログイン',
		コンポーネント:aa
	},
	{
		パス: '/home',
		名前:'ホーム',
		コンポーネント:cc
	},
	]
})

上記は一般的なプロジェクトのルーティング設定です。ここで認証を行う必要があるため、ルーティング設定テーブルを次の 2 つの配列に少し分割する必要があります。

'vue' から Vue をインポートします
'vue-router' から Router をインポートします。

Vue.use(ルーター)

export const defaultRoute = [ //固定部分権限の配列、すべてのユーザーがアクセスできるルート {
		パス:'/login',
		コンポーネント:aa
	},
]

export const asyncRoute = [ //動的に構成されたルーティングテーブル。動作する前にフィルタリングする必要があります {
		パス:'/order',
		名前:'注文',
		コンポーネント:aa、
		メタ:{
			システム:'注文'
		}
	}
	{
		パス:'/roles',
		名前:'役割',
		コンポーネント:aa、
		メタ:{
			システム:'役割'
		}
	}
]

//ルーティングテーブルを登録 const createRouter = () => new Router({
	  // モード: 'history'、// サービスサポートが必要
	  スクロール動作: () => ({ y: 0 }),
	  ルート: 定数ルート
})
定数ルーター = createRouter()

//ルーティングワークシートをリセットします。このメソッドはログアウト時に呼び出す必要があります。export function resetRouter() {
  定数 newRouter = createRouter()
  router.matcher = 新しいRouter.matcher 
}

デフォルトルーターをエクスポートする

permission.js権限ファイルは、主にグローバル ルーティングのインターセプトと、ユーザー権限に応じたルーティングの動的フィルタリングに使用されます。この部分には、動的ルーティングをいつ処理するか、どのような条件でルーティングを処理するかという 2 つの問題が主に関係します。

'./router' からルーターをインポートします
'./store' からストアをインポートします
import { getToken } from '@/utils/auth' // トークンにアクセスするためのカスタムカプセル化メソッド Route.beforeEach((to,from,next) =>{
	// ユーザーがログインしているかどうかを判断するためのトークンを取得します。const hasToken = getToken() 
	トークンがある場合
	//ユーザーがログインしたかどうかを判断します if (to.path === "/login") {
			/**
			*ユーザーはログインしていますが、ログインページにルーティングされます。これは、ユーザーがログアウト操作を実行したことを意味します。そのため、この場所でトークンをクリアするか、カスタムロジックを記述することができます。*/
			次()
		}それ以外{
		/**
		*ここでは、ユーザーがログインしているかログイン ボタンをクリックした場合、トークンはローカル ストレージに保存されていますが、ログインにルーティングされていません。/login へのルートがない場合は、そのままにしておきます。ここでいくつかの処理を行います。つまり、ユーザーがログインして直接解放できるため、解放する前に、ここでいくつかのロジックを実行する必要があります。つまり、ユーザーの権限を判断し、動的に構成されたルーティング テーブルで、ユーザーの権限に基づいて権限を満たすルートをフィルター処理し、それらをルーティング構成テーブルに挿入して使用します。*
		* ここで、2 つの問題が関係します。
		*1: 動的ルーティングを処理するタイミング(ログイン後、ホームページに入る前、つまり*次へ進む前)
		*2: 動的ルーティングを処理する条件 */
		
		/**
		*ここで、まずストア内のユーザー権限リストの長さが 0 かどうかを確認できます。長さが 0 の場合、ユーザーはログイン ボタンをクリックしただけで、ページに入っていないことを意味します。このとき、権限フィルタリングを行う必要があります。	
		*長さが0でない場合は、認証プロセスが正常であることを意味します。対応するコンポーネントに直接移動してください。 *この手順は主に、配列の繰り返しフィルタリングを防ぎ、パフォーマンスを節約するためのものです。 */
			store.getters.roles.length > 0 の場合 {
				次()
			}それ以外{
				//コードがこの時点に到達した場合、ユーザーはログインしていることを意味します。認証プロセスはまだ開始されていません。
				//ここで認証プロセスを実行する必要があります store.dispatch('getRoles').then(res=>{
					// ここでの res は、3 番目のステップの peomise の解決です // これは権限情報の配列です store.dispatch('createRouters',res.data)
					.then(res=>{
						// これは、ストアを呼び出して動的ルートを作成する関数です。この関数に // 権限配列を渡すことも、ここで渡すこともできます。 // この関数は、同じ方法で状態内のロールの値を直接取得します。 let addRouters = store.getters('addRouters')
						allRouters を store.getters('allRouters') にします。

						// 動的ルーティング部分を作業ルートに追加します router.addRoutes(accessRoutes)
						// インターセプトされたページに移動します next({ ...to, replace: true })
					})	
				})
			}
		}
	} それ以外 {
		/** ここでは、トークンがない、つまりユーザーがこの時点でログインしていない状況を処理します。ログインしているユーザーがいない場合は、ユーザーがログイン ページに行くかどうかを判断します。ログイン ページの場合は、直接アクセスします。ユーザーがログインせずにホームページにアクセスしたい場合は、ログイン ページにリダイレクトします。*/
		to.path == '/login'の場合{
			//この場所はもっと慎重に判断できます。ログイン時に直接行かせる必要はありませんが、 //すべてのパブリックコンポーネントに行くときは、直接次に行かせます()
		}それ以外{
			次へ('/ログイン')
		}
	}
}) 

 

ストア

// api フォルダーでユーザーの権限を取得するためのインターフェースを定義し、このアクションで呼び出しますimport { getUserRole } from "../api/getRoles" // 権限を取得するためのインターフェースimport { logout } from '../api/user' // ユーザー ログアウトのためのインターフェースimport { resetRouter } from './router'
import { removeToken } from '@/utils/auth' // トークンをクリアするためのカスタムカプセル化メソッド // これは配列をフィルタリングするメソッドです。ルーティングテーブルが複数のレイヤーにネストされている場合は、このメソッドを再帰的に呼び出して配列をフィルタリングできます //function hasPermission(roles, route) {
// (route.meta && route.meta.roles) の場合 {
// roles.some(role => route.meta.roles.includes(role)) を返します
// } それ以外 {
// true を返す
// }
//

//関数 filterAsyncRoutes(routes, roles) をエクスポートします。
// 定数 res = []

// ルート.forEach(ルート => {
// const tmp = { ...ルート }
// if (hasPermission(roles, tmp)) {
// if (tmp.children) {
// tmp.children = filterAsyncRoutes(tmp.children, ロール)
// }
// res.push(tmp)
// }
// })
//
// resを返す
//

// デフォルトルーティングと動的ルーティングを導入する import { defaultRoute , asyncRouter } from '@/router'
定数状態 = {
	roles: [] //インターフェースによって取得される権限リスト。データ形式は次の通り: ["order", "roles"],
	allRouters: [], //これはすべての統合後の最終的な作業ルートです addRouters: [], //これは権限の動的な一致に従ってフィルタリングされたルートです}
	  
const ゲッター = {
	/** このゲッター内の状態の役割を保存し、このゲッター内の役割を取得する他の場所では、元の役割が変更される限り、他の場所の役割も変更されます。これは、計算されたプロパティと同等です */
	ロール:状態 => 状態.ロール
	allRouters:状態 => 状態.allRouters
	addRouters:state => state.addRouters
}
const 変異: {
	/**次のアクションでは、権限情報の配列をコミットを通じてこの場所に送信し、*この場所は配列を状態のロールに送信します
	*/
	SetRoute(状態、ルーター)
		//ここでのルーターは、ユーザー権限に応じてフィルタリングされたルーティングテーブルです。state.allRouters = defaultRoute.concat(router)
		state.addRouters = ルーター
	}
	//ルーティング許可配列を状態に保存する
	setRoles(状態、値){
		状態.役割 = 値
	}
}
定数アクション: {
	//現在ログインしているロールの権限を取得するリクエストを記述します。例: ["/order","roles"]。リクエストがこのように返された場合、このロールの権限は order ルートと roles ルートへのアクセスであることを意味します。	
	// 権限情報を取得する状況は 2 つ考えられます。ただし、次の権限情報は別のインターフェイスです。
	// 権限情報は、ユーザーログインインターフェースと一緒に返される場合もあります // 現在のユーザーの権限情報を取得し、状態に格納します。この権限情報は、バックエンドと通信される場合があります // リクエストするための別のインターフェースとして記述されることはありません。代わりに、ログインすると、ユーザー情報とユーザーの権限情報が一度に返されます。その後、ユーザーがログインすると、権限情報が状態に格納されます。 // 目的は、権限情報の配列を状態に格納することです。 // ロールの権限を取得するメソッド getRoles({commit},data){
		新しいPromise(resolve,reject)を返す{
			// ユーザー権限を取得するには、インターフェイス getUserRole() を呼び出します。その後 (res =>{
				//ここで返されるデータは、次のような権限情報の配列である必要があります: ["order", "roles"]
				//ミューテーションを通じて権限情報を状態に保存する
				コミット('setRoles',res.data)
				解決(res.data)
			})
		}
	})
	//権限に基づいて配列構成テーブルをフィルタリングするメソッド createRouters({ commit } , data ){
		新しい Promise を返します ((resolve,reject) => {
			addRouters = [ ] とします 
			if (data.includes("admin") {
				追加ルーター = 非同期ルーター
			}それ以外{
				// プロジェクト開発では、ルーティング配列が複数のレイヤーにネストされる可能性があるため、この場所では上記のカスタムメソッドを使用する必要があります	
				// 再帰的にフィルタリングするメソッド。このデモでは配列の 1 つのレイヤーのみを処理します //(filterAsyncRoutes) メソッド addRouters = asyncRouter.filter(item=>{
					if (data.includes(item.meta.system) ) {
					   	返品商品
					}
				})
			}
			
			
			//一致した権限ルートをmutationsに渡し、mutationsを
			//一致したルートを状態に保存する
			コミットします。("SetRoute",addRouters)
			resolve() //ここでresolveを呼び出す必要があります。これにより、外部のユーザーは、//.thenを通じて配列フィルタリングが成功したというコールバックを取得できます。})
	},
	ログアウト({コミット}){
	    新しい Promise を返します ((resolve, reject) => {
	      ログアウト().then(() => {
	        removeToken() // 最初にトークンを削除する必要があります
	        ルータをリセットする()
	        コミット('setRoles', [])
	        コミット('SetRoute', [])
	        解決する()
	      }).catch(エラー => {
	        拒否(エラー)
	      })
	    })
  },
}
エクスポートデフォルト{
	州、
	ゲッター、
	突然変異、
	アクション
}

ログアウト:

非同期関数logout(){
	試す{
		const res = store.dispatch.logout() を待機します
		(res.code == 200){
			//ログアウト成功 }
	}キャッチ{
		//ログアウトに失敗しました(エラー)
	}
}

エンディング:

コードはたくさんありますが、考え方は非常にシンプルで、ルーティング構成テーブルを取得し、配列をフィルタリングして動的に追加するだけです。

プロジェクトリファレンス github: vue-element-admin

これで、vue要素のバックグラウンド認証プロセスの分析に関するこの記事は終了です。より関連性の高いvue要素認証コンテンツについては、123WORDPRESS.COMで以前の記事を検索するか、次の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMを応援してください。

以下もご興味があるかもしれません:
  • Vue+elementUI コンポーネントは、折りたたみ可能な動的レンダリングのマルチレベル サイドバー ナビゲーションを再帰的に実装します。
  • プレーヤー機能を実現するためのvue + element uiのサンプルコード
  • Vue ベースの要素ボタン権限実装ソリューション
  • Vue+element+oss はフロントエンドのフラグメントアップロードとブレークポイント再開を実現します
  • 要素 DateTimePicker+vue ポップアップボックスに時間のみが表示される問題を解決する
  • VueはElementUIのフォームサンプルコードを模倣する
  • Vueを使用してツリーコンポーネントを実装する例
  • ツリーコントロールを使用した Vue+iview の具体的な使用法
  • Vue での編集可能なツリー テーブルの実装コード
  • Vue Element フロントエンドアプリケーション開発ツリーリストコンポーネント

<<:  lnmp を使用して MySQL データベースのルート パスワードをリセットする 2 つの方法

>>:  Linuxカーネルマクロcontainer_ofの詳細な分析

推薦する

HTML フォーム_PowerNode Java アカデミー

1. フォーム1. フォームの役割HTML フォームは、さまざまな種類のユーザー入力を受け取り、ユー...

JavaScript ESの新機能letとconstキーワードに基づく

目次1. letキーワード1.1 基本的な使い方1.2 変動昇進はない1.3 一時的なデッドゾーン1...

Vueは質問応答機能を実装する

1. リクエスト回答インターフェース2. ユーザーの回答が正しいかどうかを判断します。回答が正しい場...

HTML 左、中央、右の適応レイアウト (calc css 式を使用)

最新の HTML 標準には、レイアウトを計算するために使用できる calc CSS 式があります。し...

サイトマップをウェブページの下部に配置するメリットと例

以前は、ほとんどすべての Web サイトに、すべてのページをリストしたサイトマップ ページがありまし...

JavaScriptで計算機機能を実現するプロセスの詳細な説明

目次1. 電卓機能の紹介2. 計算機ページのデザイン1. ナビゲーションバー2. データ部分3. i...

MySQL クエリ キャッシュのグラフィカルな説明

目次1. 原則の概要クエリキャッシュシステム変数1. クエリキャッシュを持つ2. クエリキャッシュ制...

Vue テンプレート構成と Webstorm コード形式仕様設定

目次1. コンパイラコードフォーマット仕様設定2. Vueテンプレートの設定1. コンパイラコードフ...

Vueルーティングナビゲーションガードの簡単な理解

目次1. グローバルガード1. グローバル前線警備2. グローバル解像度ガード3. グローバルポスト...

CentOS システムのディスク パーティションを拡張する方法

問題/障害/シナリオ/要件Eve-ng の仮想マシン OVA のハードディスクは 38G しかないた...

Oracle の MySQL バージョンでユーザー Scott のテーブル ステートメントを作成する例

概要: Oracle scottユーザーには4つのテーブルがあり、実験やデータ検証に便利です。現在は...

HTML スタイル タグと関連する CSS リファレンスの詳細な説明

HTML スタイル タグスタイルタグ - ドキュメント内でスタイルを宣言するときにこのタグを使用しま...

HTML 形式の JSON 出力の例 (テスト インターフェース)

JSON データを美しいインデント形式で表示するには、最も単純な JSON.stringify 関...

MySQLは現在の日付と時刻を取得する関数の例の詳細な説明

現在の日付 + 時刻 (日付 + 時刻) を取得する関数: now() mysql> now(...

MySQLクエリトランザクション処理へのノード接続の実装

目次トピックmysqlの追加、削除、変更、クエリを入力しますMySQL トランザクション処理私は M...