権限制御とは何ですか?
プロジェクト、特にバックグラウンド管理システムでは、さまざまな担当者がログインし、さまざまなページ メニューが表示されます。たとえば、会社のオフィス システムでは、上司がログインするとすべてのページが表示され、一般の従業員はログインするとすべてのページが表示されます。ログインしても、会社の業績や収益のページを表示できない場合があります。たとえば、会社の従業員プロフィール ページを表示できるのは人事部門のみであり、他の部門の従業員は会社の従業員情報データを表示することはできません。
もちろん、ページの権限に加えて、ダウンロード ボタンなど、一部のアカウントでは使用できるが、他のアカウントでは使用できないボタン レベルの権限もいくつかあります。たとえば、学校システムには、ページ上で成績を確認します。教師にはクリックする権利がありますが、ログインしている他の生徒はクリックできません。
1.页面级的权限(用户是否有权限能看到这个页面)
2.按钮级的权限(用户是否能看到或者能用页面中的某个按钮)
ページレベルの権限制御 (1)
1. バックエンドはルーティング情報を返し、フロントエンドは完全なルーティング テーブルを保存します。
前端拿到路由信息采取递归的方式动态生成页面菜单。
自己本身的router.js文件定义好页面所有的路由。这种方式弊端很明显,并不能实现真正的权限控制,
因为如果用户记住了某个路由,用户不点击菜单,直接在地址栏里输入地址,那么页面还是可以显示出来
2. バックエンドはルーティング権限名を返し、フロントエンドは完全なルーティング権限テーブルを保存し、ルートを動的に生成します (実権限制御)
首先前端router.js文件存储的路由配置信息会分为两部分,分别是需要权限的和不需要权限的。
页面一开始不能一个路由没有,所以会有一些不需要权限的页面,比如登录页,404页面等。所以一开始直接渲染
这个不需要权限的路由表,等后台返回之后再把需要权限的路由加到当前路由里面形成一个全新的路由表就可以了
router.js 権限を必要としないルーティング テーブル
const route = [
{
path: '/',
redirect: '/login',
},
{
path: '/login',
name: '登录页面',
component: ()=>import("@/views/login.vue")
},
{
path: '/404',
name: '404页面',
component: ()=>import("@/views/404.vue")
},
]
router.js 権限が必要なルーティング テーブル 権限が必要な
ページの場合、現在のルートに必要な権限を示すフィールド ロールをルートのメタ属性に追加します。
このロールはキーワードではないことに注意してください。別名。メタの値が配列である理由については、将来的に一部のページで一般ユーザー、管理者、スーパー管理者など異なる権限が付与される可能性があることを考慮しています。
export const asyncRouterMap = [
{
path: '/permission',
name: 'permissionhome',
meta: {
icon: 'el-icon-setting',
roles: ['admin','superadmin']
},
component: ()=>import("@/views/permission.vue")
},
{
path: '/detail',
name: 'detail',
meta: {
icon: 'el-icon-setting',
roles: ['superadmin']
},
component: ()=>import("@/views/detail.vue")
},
ユーザーがログインすると、ログイン インターフェイスは次の構造に似た権限名の文字列を返します。
{
code:200,
success:true,
result:{
name:"张三",
opid:11024,
role:"admin"//此字段是拥有的权限名字
}
}
許可名を取得したら、許可を必要とする作成したルーティング テーブルを調べて、それらを 1 つずつ比較します。
このデータはグローバルに使用する必要があるため、通常、ログイン後に取得した情報を vuex に保存します。(vuex への入れ方と取り出し方については詳しく説明しません。必要に応じて、最初に vuex について学習してください。後で誰でも読めるように整理します)
新しい js ファイルを作成します。
具体的な操作は、非同期ルーティング テーブルを導入し、ループを作成することです。
import {asyncRouterMap} from "../router.js".
filter メソッドを使用して、返されたロール権限名と一致するルーティング リスト内のロール権限内の項目をフィルタリングして除外します。
asyncRouterMap.filter()
メソッドを使用して、フィルタリングされたルーティング テーブルを現在のプロジェクトのルーティングに追加します。ルート ルーティング インスタンスのこのメソッドを呼び出すことによって、任意のルーティング設定を現在のページ ルーティングに追加できるため、新しいルーティングを生成できます。実質的な管理権限の目的を達成した
router.addRoutes(筛选之后的路由表)
ページ レベルのアクセス許可制御 (2)
2 番目のメソッドは、バックエンドがアクセス許可名を返さないことと、フロントエンドが非同期ルーティング テーブルをローカルに保存しないことを除いて、実際には最初のメソッドの簡略化されたバージョンです。テーブルを追加し、フロントエンドが addRoutes メソッドを通じてテーブルを直接追加します。
この方法の利点は、フロントエンドの作業負荷が軽減されることですが、実際の作業はさらに面倒です。ルーティング テーブルが維持されるため、フロントエンドがアクセス許可を追加する必要があるたびに、バックエンドがアクセス許可の追加を支援する必要があります。バックエンドで。
ボタンレベルの権限制御 (1)
たとえば、ボタンはスーパー管理者のみが表示でき、他の権限は表示されません。その場合、上記の最初のステートメントに従って、返された情報から役割フィールドを取得し、ボタン
のページはこのように書くことができます
html
<button v-if="role=='superAdmin'">权限按钮</button>
js
export default{
computed:{
//当然实际工作中这里一般都使用mapState
role:this.$store.state.role
}
}
これにより、ボタンレベルでの許可制御が実現できる。特殊なケースでは、role が配列の場合、indexOf メソッドを使用して、アクセス許可配列内のパッケージに、このボタンに必要なアクセス許可が含まれていないことを確認できます。原理はほぼ同じです。
ボタンレベルの権限制御 (2)
2 番目の方法はカスタム命令を使用するもので、原理はほぼ同じです。
1. まず、バックエンドによって返された権限の名前を取得します
。 2. カスタム コマンドをグローバルに定義します。
Vue.directive('per', {
bind: (el, binding, vnode) => {
//roles是我们的权限数组,binding.value是我们传入自定义指令的值
//如果找不到,那证明没有权限,把当前元素节点移除掉
if (roles.indexOf(binding.value)==-1) {
el.parentNode.removeChild(el);
}
}
使用
//这个传入的admin是对应上面binding.value
<div v-per="[admin]">
admin 可见
</div>