celsomtrindade
celsomtrindade

Reputation: 4671

AngularJs Check if user role matchs state role for authentication

I'm building an authentication system and I've done almost everything. I'm stuck in the authorization based on user role. If I use numbers, like user.role > 1, pass, if not, return false, I can make it work properly.

But I'm planning to move to an array based role, so I can create 'modules' and make a better control.

Auth process

It all starts with a return from the database, if the user/pass is ok, the DB will return a json array containing user name, id and roles, like this:

{
    id: 1,
    name: 'John Doe',
    role: ['user', 'order', 'service']
}

In my $state, i have it defined like this:

.state('home', {
    [...code...]
    data: {
        requireLogin: true,
        role: ['user']
    }
})
.state('sales', {
    [...code...]
    data: {
        requireLogin: true,
        role: ['sales', 'admin']
    }
})
.state('order', {
    [...code...]
    data: {
        requireLogin: true,
        role: ['order', 'admin']
    }
})

So for example, that user should be able to access the state 'order' and 'home', because at least one of the roles is in the .state data role. But I'm having trouble validating it inside my factory. I kind of made it, but sometimes it returns some other unxpected numbers, or at least i don't know the proper validation.

This is my factory:

//token = user data returned from data base;
//type = user role from state;
var _getTipo = function(token, type) {
    var authUser = token.indexOf(type);
    return authUser;
};

Sometimes i get the return -1, 10 or 2..

What i did wrong? Or whats the proper way to check if at least one of the user roles is in the state role?

Upvotes: 0

Views: 1707

Answers (1)

jrkt
jrkt

Reputation: 2715

Whenever I do user authentication I use a directive as an attribute like this:

app.directive('permissions', function (currentUser) {
        return {
            restrict: 'A',
            priority: 100000,
            scope: false,
            link: function (scope, element, attr) {
                var accessDenied = true;

                var attribute = attr.permissions;
                if (currentUser.role.indexOf(attribute) !== -1) {
                    accessDenied = false;
                }

                if (accessDenied) {
                    element.children().remove();
                    element.remove();
                }

            }
        };
    });

You would then call it like this:

<div permissions="user">
   //info
</div>

You would just need to pass the currentUser object to the directive. Or you could just change your factory:

var _getTipo = function(token, type) {
    var authenticated = false
    for(var i = 0;i < token.role.length;i++){
        var userRole = token.role[i];
        for(var x = 0;x < type.length;x++){
            var stateRole = type[x];
            if (userRole == stateRole) {
                authenticated = true;
            }
        }
    }
    return authenticated;
};

To turn this string: "['user', 'sales']" into an array:

JAVASCRIPT

var string = "['user', 'sales']";
var array = string.replace('"[',"").replace(']"',"").split("', '");

PHP

$string = "['user', 'sales']";
$string = str_replace('"[',"",$string);
$string = str_replace(']"',"",$string);
$array = explode("', '",$string);

Upvotes: 1

Related Questions