Ролевой контроль доступа к веб-приложению Mean stack

Я работаю над веб-приложением среднего стека, которое содержит дифференциальный доступ на основе роли зарегистрированного пользователя. существует несколько разных ролей, таких как администратор, правительство, волонтер и т. д.

<сильный>1. как управлять внешним интерфейсом в зависимости от роли?

в настоящее время я устанавливаю глобальные флаги, такие как isAdmin, isVolunteer, isGovt и т. д. для каждой роли, и в зависимости от их значения я могу отображать другой пользовательский интерфейс, используя data-ng-if = "Global.isAdmin"

Является ли этот подход правильным. если нет, предложите правильный способ обработки пользовательского интерфейса.

<сильный>2. как управлять серверной частью и перенаправить маршрут, если у пользователя не было авторизации?

в настоящее время я пытаюсь использовать angular-permission и rbac, но все еще не могу успешно использовать их в своем приложении. кто-нибудь может рассказать мне о лучших методах управления доступом на основе ролей для веб-приложения среднего стека.

при попытке использовать angular-permission мне не удалось связать созданные роли с файлом маршрута.

это ролевой модуль.

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
            }

        });

person ashishkumar148    schedule 25.03.2015    source источник
comment
@JonSamwell Я думаю, хорошо дать очень краткий ответ, по крайней мере, концептуальный, а затем сразу же сослаться на свой пост;)   -  person diegoaguilar    schedule 25.03.2015


Ответы (1)


Судя по вашим примерам кода, вы используете mean.io.

Это мой подход к управлению доступом на основе ролей во внешнем интерфейсе в mean.io.

В первую очередь я добавляю роли некоторым пользователям, чтобы они существовали в базе данных и я мог их использовать.

$ mean user [email protected] --addRole production
$ mean user [email protected] --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/#!/report/sales и вы увидите отчет о продажах независимо от того, есть ли у вас роль продавца или нет.

Хитрость заключается в файле public/routes/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)
            }
        }
    });
  }
]);

Если пользователь не авторизован, он перенаправляется на страницу авторизации. Если у него неправильная роль, он перенаправляется на главную страницу.

Этот подход основан на модуле статей. Надеюсь, поможет.

person Juangui Jordán    schedule 21.04.2015