Vishnu Sureshkumar
Vishnu Sureshkumar

Reputation: 2316

Best way to show/hide a part based on permission level - Angular JS

I have an AngularJS Single Page Application where there are lot of HTML blocks which I show to users based on their permission levels.

The user permission is determined by service calls and a value is set based on permission.

$scope.permission = 'admin'

I can use ng-hide/show directives to hide those blocks based on permission. But I am worried about security. By changing the css display property those who are not authorized can also view those blocks.

The other option is ng-if, which I am using currently. But I would like to know whether I should do the same with routing, which is more secure, I believe. I can use ui.router angular module to acheive this. But what is the right way?

Should I use ng-hide/show, ng-if or routing?

Expecting some good thoughts.

Any help is greatly appreciated. Thanks in advance.

Upvotes: 0

Views: 9387

Answers (4)

rishi
rishi

Reputation: 19

As replied by Coder John, the User will always be able to hack this. Even you can make it harder using directive or ngif condition, but since they have access to the full source code, it can always be modified Client side.

As suggestion written above the element itself remove if we use directive or ngif approach. Is there way to remove java script function too which written to handle Click event of button? Since i am putting directive or ngif condition on button element.

Best regards.

Upvotes: 0

Chandermani
Chandermani

Reputation: 42669

To handle authorization from a route perspective, we can build some custom extensions to the angular routing infrastructure. The routes can be defined as

$routeProvider.when('/admin', {
    templateUrl: 'admin.html',
    controller: 'AdminController',
    roles: ['admin']  //custom extension
});
$routeProvider.when('/home', {
    templateUrl: 'home.html',
    controller: 'HomeController',
    roles: ['admin', 'user'] //custom extension
})

Here the role array define who has access to the route.

To enforce it we can use the routeChangeStart event to verify rights. This is an excerpt from my book which highlights how to enforce roles

angular.module('app').run(function ($rootScope, $location,
SessionContext) {
    $rootScope.$on('$routeChangeStart', function (event, next) {
        if (next.roles && !SessionContext.authenticated) {
            $location.path('/login'); //needs to login
        }
        if (next.roles && SessionContext.authenticated && !SessionContext.isInRole(next.roles)) {
            $location.path('/unauthorized'); //un-authorized
        }
    });
});

The SessionContext service tracks the loggedin user roles.

Upvotes: 4

Coder John
Coder John

Reputation: 786

You should create a directive for such purpose:

app.directive('checkPermissions', ['PermissionsServices', function(PermissionsServices) {
    return {
        restrict: 'A',
        link: function(scope, elem, attrs, ctrl) {

            if (attrs.permissions != '') {
                var hasPermission = PermissionsServices.hasAccess(attrs.checkPermissions);

                if (false == hasPermission) {
                    elem.remove();
                }
            } else {
                elem.remove();
            }
        }
    };
}]);

HTML Section

<a href="http://some_url" check-permissions="state1.name1" >Some URL</a>
<a ui-sref="state2.name2" check-permissions="state2.name2">State 2</a>
<button ng-click="state3.name" check-permissions="state3.name3">State 3</button>

PermissionsServices.hasAccess() function in the PermissionsServices service will check if the User has access to particular state of your application. You might be using Angular Router or UI Router for handling states. I am using UI router so my code in the function is below. This function will just return true or false.

PermissionsServices.hasAccess = function(stateName) {
        var hasAccess                   = false;


        //Some complex checking algorithm based on your requirement
        hasAccess = true

        return hasAccess;
};

Hope that helps!!

Upvotes: 8

alan.kehoe
alan.kehoe

Reputation: 41

Basically ng-if add/removes the element to the DOM where ad ng-show/ng-hide just hides the element with css.

routing is also a viable option but this way you will have multiple partials for different users. if you just want to hide some stuff from some users I would go with ng-if

Upvotes: 4

Related Questions