AngularJS + UI Router: checking authorization and access rights

  • Tutorial
If your application involves authorizing users and / or checking access rights, then you will either have to reinvent the wheel or google in search of a suitable solution. Basically, I did it too. In the end, I accepted the option described below that was acceptable to me.

Background


I decided to store information about the authorized user in sessionStorage, copying it when I started the application in $rootScope. Also, on the recommendation of the authors of the UI Router, I store objects $stateand values ​​in $ rootScope $stateParamfor easy access. Information about access to a particular state can be transmitted through the block datawhen describing the state itself. Since access is denied everywhere in my application, I decided to go from the opposite and add a value noLogin = truefor states that do not require authorization, such as a 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: ''
        })
      .state('auth.login', {
        url: '/login',
        templateUrl: 'src/auth/partials/login.html', 
        data: {
          'noLogin': true
        }
      });
  ]);


Creating a service for pre-routing


You need to check 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 manages not states, but states. Read more in the official documentation). A good way to do this is to hang the listener on an event $stateChangeStartin the run () method of your main module. In order not to clutter up the body of the method with functionality, which can be voluminous and complex, I put it in a separate service, in the method run()I just call the service method. I think no further explanation is 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, the last touch remains, so that it all works - hang the listener on a service event $state.

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 verification of access rights with any kind of goodies. For example, in the same block, datawhen describing the status, you can transfer any RBAC rules and then check them in your service.

Only registered users can participate in the survey. Please come in.

What do you use for route management in Angular JS?

  • 39.8% ngRoute 296
  • 62.1% UI Router 462
  • 1.8% I know a better solution (write in the comments) 14
  • 2% I myself wrote a router (share) 15

Also popular now: