Search code examples
javascriptangularjsangular-ui-routerangular-fullstack

Authenticate on stateProvider for a specific user (angular-fullstack)


I use angular-fullstack generator for my project(https://github.com/angular-fullstack/generator-angular-fullstack) and I have a demand page on my website who needs to be accessible by users with a defined role(admin). This page also needs to be accessible by the user who has created the demand.

I know that I can put authenticate:true on my state provider to authorize only the authenticated users but I need a more precise system for my situation because I need to allow only users with a specific role or a specific user id.

Is there a way to manage this case in the stateProvider or must I be doing this in my page controller, after the $state redirection?

Thanks for your time


Solution

  • Authorization for specific role can be done but you need to modify some code.

    Add a new field access to your state configuration file as follows. Let's store the authRequiredFor array in that which contain the roles which require authorization to access that particular state myState.

    angular.module('myApp')
        .config(function ($stateProvider) {
        $stateProvider
          .state('myState', {
            url: '...',
            templateUrl: '...',
            controller: '...',
            access: {
                authRequiredFor: ['role1', 'role2']
            }                
        });
    });
    

    In your app.js file in the run() function, you need to add and modify the $stateChangeStart callback function to check whether the user needs authentication or not before accessing any state.

    .run(function ($rootScope, $location, Auth, $state) {
        // Redirect to login if route requires auth and you're not logged in
        $rootScope.$on('$stateChangeStart', function (event, next) {
            Auth.isLoggedInAsync(function(loggedIn) {
                if (next.authenticate && !loggedIn) {
                    $location.url('/login');
                }
                if (next.access) {  // check if the state config contains the field `access`
                    var permissions = next.access;
                    var userRole = Auth.getCurrentUser().role;
                    if (permissions.authRequiredFor) {
                        // check if the logged in user's role matches with the roles in the array
                        if (permissions.authRequiredFor.indexOf(userRole) >= 0) {
                            $location.url('/login'); // or redirect him to some other url/state
                        }
                    }
                }        
            });
        });
    });
    

    Hope this solves the issue.