Управление доступом на основе ролей в веб-приложении Mean stack
Я работаю над веб-приложением со средним стеком, которое содержит дифференциальный доступ в зависимости от роли зарегистрированного пользователя. Есть несколько разных ролей, таких как администратор, правительство, волонтер и т. д.
1. как управлять интерфейсом на основе роли?
в настоящее время я устанавливаю глобальные флаги, такие как isAdmin, isVolunteer, isGovt и т. д. для каждой роли, и, основываясь на их значении, я могу отображать различные интерфейсы, используя data-ng-if = "Global.isAdmin"
Является ли этот подход правильным? если нет, пожалуйста, предложите правильный способ обработки пользовательского интерфейса.
2. как управлять серверной частью и перенаправлять маршрут, если у пользователя не было авторизации?
В настоящее время я пытаюсь использовать Angular -разрешения и RAB, но все еще не могу успешно использовать их в моем приложении. Кто-нибудь может рассказать мне лучшие практики для управления доступом на основе ролей для веб-приложения среднего стека.
при попытке использовать угловое разрешение я не смог связать созданные роли с файлом маршрута.
это ролевый модуль.
angular.module('mean.users', ['permission'])
.run(['permission', 'Global', '$q',
function(Permission, Global, $q) {
console.log('not anonumous');
Permission
.defineRole('anonymous', function(stateParams) {
var deferred = $q.defer();
if (Global.user) {
deferred.resolve();
} else {
deferred.reject();
}
return deferred.promise;
})
.defineRole('admin', function(stateParams) {
if (Global.isAdmin) {
deferred.resolve();
} else {
deferred.reject();
}
return deferred.promise;
})
.defineRole('govt', function(stateParams) {
if (Global.isGovt) {
deferred.resolve();
} else {
deferred.reject();
}
return deferred.promise;
})
.defineRole('volunteer', function(stateParams) {
if (Global.isVolunteer) {
deferred.resolve();
} else {
deferred.reject();
}
return deferred.promise;
});
}
]);
как связать выше сконфигурированные роли в файле маршрута
$stateProvider
.state('create user', {
url: '/users/create',
templateUrl: 'users/views/create.html',
resolve: {
loggedin: checkLoggedin
}
})
.state('all users', {
url: '/users/list',
templateUrl: 'users/views/list.html',
data: {
permissions: {
only: ['admin'],
redirectTo: 'home'
}
}
})
.state('show user', {
url: '/users/:userId/view',
templateUrl: 'users/views/view.html',
resolve: {
loggedin: checkLoggedin
}
})
.state('edit user', {
url: '/users/:userId/edit',
templateUrl: 'users/views/edit.html',
data: {
permissions: {
only: ['admin']
}
}
})
.state('myprofile', {
url: '/users/:userId/me',
templateUrl: 'users/views/myprofile.html',
resolve: {
loggedin: checkLoggedin
}
});
1 ответ
Из ваших примеров кода, я думаю, вы используете mean.io.
Это мой подход к управлению доступом на основе ролей на внешнем интерфейсе, в mean.io.
Прежде всего, я добавляю роли некоторым пользователям, чтобы они существовали в базе данных, и я мог их использовать.
$ mean user a@example.com --addRole production
$ mean user b@example.com --addRole sales
Затем у меня есть 2 маршрута, чтобы добавить в меню. В app.js моего пользовательского модуля я фильтрую эти маршруты по ролям, чтобы ссылки не показывались другим ролям:
Report.menus.add({
roles: ['production'],
title: 'Production reports',
link: 'production reports'
});
Report.menus.add({
roles: ['sales'],
title: 'Sales reports',
link: 'sales reports'
});
Конечно, этого недостаточно для ограничения доступа в веб-интерфейсе. Вы можете легко указать на http://localhost:3000/ и увидеть отчет о продажах, независимо от того, выполняете ли вы роль или нет.
Хитрость содержится в файле public/route /report.js моего пользовательского модуля, где я фильтрую представления по ролям.
'use strict';
angular.module('mean.report').config(['$stateProvider',
function($stateProvider) {
// Check if user has role
var checkUserRole = function(role, $q, $timeout, $http, $location) {
// Initialize a new promise
var deferred = $q.defer();
// Make an AJAX call to check if the user is logged in and get user data including roles
$http.get('/loggedin').success(function(user) {
// Authenticated
if (user !== '0' && (user.roles.indexOf(role) > -1 || user.roles.indexOf('admin') > -1)) $timeout(deferred.resolve);
// Not Authenticated
else {
$timeout(deferred.reject);
$location.url('/auth/login');
}
});
return deferred.promise;
};
$stateProvider.state('report', {
url: '/report',
templateUrl: 'report/views/index.html'
})
.state('production reports', {
url: '/report/production',
templateUrl: 'report/views/production.html',
resolve: {
loggedin: function($q, $timeout, $http, $location) {
return checkUserRole('production', $q, $timeout, $http, $location)
}
}
})
.state('sales reports', {
url: '/report/sales',
templateUrl: 'report/views/sales.html',
resolve: {
loggedin: function($q, $timeout, $http, $location) {
return checkUserRole('sales', $q, $timeout, $http, $location)
}
}
});
}
]);
В случае, если пользователь не прошел проверку подлинности, он перенаправляется на страницу входа. Если у него неправильная роль, он перенаправляется на домашнюю страницу.
Этот подход основан на модуле статей. Надеюсь, поможет.