Vue-Access-ControlЭто набор интерфейсных решений для управления разрешениями пользователей на основе Vue/Vue-Router/axios.Управляя тремя уровнями маршрутизации, просмотра и запроса, разработчики могут реализовать управление разрешениями пользователей с любой степенью детализации.
Установить
Требования к версии
- Vue 2.0x
- Vue-router 3.x
Получать
Домашняя страница проекта:уточненный-маленький.com/v UE-доступ-…
мерзавец:git clone https://github.com/tower1229/Vue-Access-Control.git
нпм:npm i vue-access-control
бегать
//开发
npm run dev
//构建
npm build
Обзор
вся идея
В начале сеанса сначала инициализируйте экземпляр Vue только с маршрутом входа и направьте маршрут на страницу входа в созданный хук корневого компонента.После успешного входа пользователя интерфейс получает токен пользователя, и устанавливает экземпляр axios для добавления в заголовки запроса.{"Authorization":token}
Реализуйте аутентификацию пользователя, а затем получите данные разрешений текущего пользователя, в основном включая разрешения маршрутизации и разрешения ресурсов, затем динамически добавляйте маршруты, генерируйте меню, реализуйте инструкции разрешений и методы проверки глобальных разрешений, а также добавляйте перехватчики запросов к экземпляру axios, поэтому пока разрешения завершены.Инициализация управления. После динамической загрузки маршрута компонент маршрутизации будет загружен и отображен соответствующим образом, а затем отобразится внешний интерфейс.
Для того, чтобы решить проблему, что браузер обновляет сброс маршрута, после получения токена необходимо сохранить его в папкуsessionStorage
, созданный хук корневого компонента отвечает за проверку наличия токена локально, если да, то можно использовать токен для получения разрешений и инициализации без входа в систему. компонент будет загружаться и отображаться правильно; правый доступ перейдет на 404 в соответствии с настройками маршрутизации; если токен недействителен, бэкенд должен вернуть код состояния 4xx, а фронтенд равномерно добавит перехватчик ошибок в экземпляр axios , выполните операцию выхода при обнаружении кода состояния 4xx и очиститеsessionStorage
данные и перейти на страницу входа, чтобы позволить пользователю снова войти в систему.
принцип наименьшей зависимости
Позиционирование Vue-Access-Control является однодоменным решением.У него нет других зависимостей, кроме Vue/Vue-Router/axios.Теоретически его можно применить к любому проекту Vue с требованиями контроля разрешений.Проект основан наwebpackРазработка шаблонов строится, и большинство новых проектов могут продолжать разработку непосредственно на основе проверенного кода. Следует отметить, что проект дополнительно вводитElement-UIа такжеCryptoJSОни используются только для разработки демонстрационного интерфейса, они не нужны и не имеют никакого отношения к контролю разрешений, вы можете выбрать сами в приложении проекта.
Структура каталогов
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,
...
}
Затем пройдите локальный полный маршрут, объединив путь в формате ключа в приведенной выше структуре в цикле, и передайтеhashMenus[route]
Вы можете судить о совпадении маршрута Конкретную реализацию см.App.vue
в файлеgetRoutes()
метод.
Если данные разрешения маршрутизации, возвращаемые серверной частью, отличаются от соглашения, вам необходимо реализовать логику фильтрации самостоятельно, если вы можете получить фактически доступные данные маршрутизации, и, наконец, использоватьaddRoutes()
Метод динамически добавляет их в экземпляр маршрутизации.Обратите внимание, что нечеткое соответствие страницы 404 должно быть размещено в конце.
Динамическое меню
Данные маршрутизации можно использовать непосредственно для создания меню навигации, но данные маршрутизации получаются в корневом компоненте, а меню навигации существует вindex.vue
В компоненте, очевидно, нам нужно каким-то образом разделить данные меню, способов много, вообще говоря, первое, что приходит на ум, это Vuex, но данные меню не будут меняться в течение всего пользовательского сеанса. наилучший сценарий использования для Vuex. , а чтобы свести к минимуму ненужные зависимости, здесь используется самый простой и прямой метод повесить данные меню в корневом компонентеdata.menuData
на, использовать на главной страницеthis.$parent.menuData
Получать.
Кроме того, в навигационное меню, скорее всего, потребуется добавить значки столбцов, которые можно добавить в маршрут, добавивmeta
Реализация данных, например сохранение класса значков или юникода в метаданных маршрутизации, доступ к метаданным можно получить в шаблоне для создания метки значка.
Одна из проблем, с которой вы можете столкнуться в многоролевой системе, заключается в том, что разные роли имеют маршрут с одним и тем же именем, но с разными функциями, скажем.Системный администратора такжеАдминистратор предприятияУ обоих есть маршрут «управление учетной записью», но их права доступа и цели различны.По сути, это два совершенно разных интерфейса, и Vue не позволяет использовать несколько маршрутов с одним и тем же именем, поэтому имя маршрута нужно различать, но дифференцированное Это будет очень неприглядно, если имя будет отображаться в интерфейсном меню. Чтобы позволить разным ролям иметь одно и то же имя меню, нам нужно только поместить два маршрута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
Функция ответа s — это палка о двух концах, потому что выражение суждения будет часто запускаться во время запущенного процесса, но на самом деле его разрешения не будут меняться в течение цикла пользовательского сеанса, поэтому, если вам нужно только проверить разрешения, использовать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-адреса с параметрами в согласованном формате, а затем оцените разрешения. В схеме реализованы следующие два формата подстановочных знаков:
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 не может получить данные заголовков, только один «Авторизация " можно добавить параметр. Используется для создания смоделированных данных.
Тестовый аккаунт:
1. username: root
password: 任意
2. username: client
password: 任意
Демонстрационный адрес:
vue-access-control.refined-x.com
Оригинальная техническая статья о фронтенде, просьба указывать источник при перепечатке: http://refined-x.com/2017/11/28/Vue2.0 User Rights Control Solution/
Если у вас есть какие-либо вопросы по содержанию статьи, пожалуйста, оставьте сообщение для обсуждения или отсканируйте QR-код ниже, чтобы присоединиться к платным вопросам «Front-end Road — Планета знаний».