Search code examples
angularjsloopbackjsstrongloop

How to restrict access to pages when using Angular and Strongloop?


Strongloop/loopback has built-in ACL to restrict access to properties and functions. My question is, when using AngularSDK, is there a proper way to restrict access to pages?

How can the authorization status be checked in the front-end? I'm using ui-router.


Solution

  • Check the AngularSDK Handling 401 Unauthorized section of the docs. You can set up a handler to detect when an API call returns a 401 Unauthorized response code and have your UI present a login form. I've done modals and full page redirects, depends on your sensibilities and the structure of your ui-router stuff.

    Put the below code (or something similar) inside of your app.js inside of a .config() block.

    Verbatim from the docs:

    // Inside app config block
    $httpProvider.interceptors.push(function($q, $location, LoopBackAuth) {
      return {
        responseError: function(rejection) {
          if (rejection.status == 401) {
            //Now clearing the loopback values from client browser for safe logout...
            LoopBackAuth.clearUser();
            LoopBackAuth.clearStorage();
            $location.nextAfterLogin = $location.path();
            $location.path('/login');
          }
          return $q.reject(rejection);
        }
      };
    });
     
    // In the Login controller
    User.login($scope.credentials, function() {
      var next = $location.nextAfterLogin || '/';
      $location.nextAfterLogin = null;
      $location.path(next);
    });
    

    Given that, you can add an event listener to $stateChangeStart, in your .run() block -

    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
      // API call here to check if you get (or simply trigger) a 401
      // whitelist states that can be accessed publicly
      // or blacklist states that cannot be accessed without auth
      // whichever is more straightforward
      // lots of attributes available to check for various metadata attached to states and determine yes/no to continue the state change
    });
    

    See here for $stateChangeStart and the arguments passed to the callback:

    http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$state

    So while it's true that a user could take full control of their browser and thwart this check and force the browser to load the view(s), they still can't access any API calls that require a valid token. So the views will load but the data will not, as long as you have proper ACLs on your sensitive remote methods.