📜 ⬆️ ⬇️

AngularJS + UI Router: check authorization and access rights

If your application involves user authorization and / or access control, then you will have to either reinvent the wheel or google to find the right solution. Basically, I did it too. In the end, I accepted the option described below acceptable to me.

Prerequisites


I decided to store information about the authorized user in sessionStorage, copying it when the application is started in $rootScope . Also, as recommended by the authors of the UI Router, I store the $state and $stateParam objects in $stateParam for easy access. Information about access to a particular state can be transmitted through the data block when describing the state itself. Since my application is denied access everywhere, I decided to go from the reverse and add the value noLogin = true for states that do not require authorization, such as the login page, password recovery, or registration.

 angular.module('myApp.auth', [ 'ui.router' ]) .config(['$stateProvider', '$urlRouterProvider', function ($stateProvider, $urlRouterProvider) { $stateProvider .state('auth', { url: '/auth', abstract: true, template: '<ui-view>' }) .state('auth.login', { url: '/login', templateUrl: 'src/auth/partials/login.html', data: { 'noLogin': true } }); ]); 


Creating a service for pre-routing


You need to check the authorization and access rights at the very beginning, before the router works, before it sends the visitor to the requested state (it is assumed that you know that the UI Router does not manage the positions, but the states. Read more in the official documentation). A good way to do this is to hang the listener on the $stateChangeStart event in the run () method of your main module. In order not to litter with the functionality of the body of the method, which can be voluminous and complex, I brought it to a separate service, in the run() method, I simply call the service method. I think no further explanation will be needed.
')
 angular.module('myApp.auth') .service('SessionService', [ '$injector', function($injector) { "use strict"; this.checkAccess = function(event, toState, toParams, fromState, fromParams) { var $scope = $injector.get('$rootScope'), $sessionStorage = $injector.get('$sessionStorage'); if (toState.data !== undefined) { if (toState.data.noLogin !== undefined && toState.data.noLogin) { //  ,   -  //     } } else { //    if ($sessionStorage.user) { $scope.$root.user = $sessionStorage.user; } else { //     -     event.preventDefault(); $scope.$state.go('auth.login'); } } }; } ]); 


Putting it all together


Well, there remains the final touch to make it all work - to hang the listener on the event of the $state service.

 angular.module('myApp', [ 'myApp.auth', 'ui.router', 'ngStorage' ]) .run([ '$rootScope', '$state', '$stateParams', 'SessionService', function ($rootScope, $state, $stateParams, SessionService) { $rootScope.$state = $state; $rootScope.$stateParams = $stateParams; $rootScope.user = null; //      $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) { SessionService.checkAccess(event, toState, toParams, fromState, fromParams); } ); } ]) 


Conclusion


I think this example is quite enough to use it as an idea and write your own authorization and access rights check with any kind of buns. For example, in the same data block, when describing a state, you can send any RBAC rules and then check them in your service.

Source: https://habr.com/ru/post/245049/


All Articles