0

I'm authenticating an angular app code given below, Basically I'm checking token from backend called if token is valid then we can allow users to view allowed page.

It's working somewhat but problem is when I'm going to /jobs page is somewhat loading then redirecting to login page but i don't want to show jobs page initially for few seconds it should be redirect quickly or it will not load jobs page.

In app.js

    var app = angular.module('ttt', ['ui.router', 'ui.bootstrap', 'ngResource', "ngStorage", "ngProgress", "ngCookies", 'angular-jwt', 'ngLodash','tagged.directives.infiniteScroll']);
app.config(['$stateProvider', '$urlRouterProvider', '$locationProvider', "$httpProvider", function ($stateProvider, $urlRouterProvider, $locationProvider, $httpProvider) {
    $locationProvider.html5Mode(true);
    $urlRouterProvider.otherwise(function ($stateParams) {
        console.log("val check", $stateParams, window.location);
        window.location.href = "/undefined";

    });
    $stateProvider.state("jobs", {
        url: "/jobs",
        templateUrl: "views/dashboard.html",
        controller: "JobController as JobCtrl",
        resolve : {
            formInfo : ["AuthService",function (AuthService) {
                return AuthService.getFormInfo();
            }]
        }
    }).state("undefined", {
        url: "/undefined",
        templateUrl: "views/pagenotfound.html",
        bodyClass: "errors errors-404 errors-centered"
    }).state("login", {
        url: "/login",
        templateUrl: "views/login.html",
        controller: "LoginController as LoginCtrl",
        resolve : {
            formInfo : ["AuthService",function (AuthService) {
                return AuthService.getFormInfo();
            }]
        }
    })
}]);
app.run(['$rootScope', 'ngProgressFactory', '$state', '$compile', '$location', '$cookies', 'jwtHelper','AuthService', function ($rootScope, ngProgressFactory, $compile, $state, $location, $cookies, jwtHelper,AuthService) {
    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams, options) {
        $rootScope.progressbar = ngProgressFactory.createInstance();
        $rootScope.progressbar.start();
        $rootScope.location = $location;
    });

  var authPreventer =  $rootScope.$on('$locationChangeStart', function (event, toState, toParams, fromState, fromParams, options) {

        var notCheckRoute = ["/undefined", "/signin", "/login"];
        //event.preventDefault();
         if(notCheckRoute.indexOf($location.path()) !== -1){
            AuthService.checkPermission()
            .then(function(data) {
                //event.preventDefault();
                if(data.active){
                    $location.path('/home'); 
                }else{
                    $location.path('/login');
                }
            });
         }else{
             //event.preventDefault();
            AuthService.checkPermission()
            .then(function(data) {
                if(!data.active){
                    $location.path('/login'); 
                }else{
                    //$location.path('/jobs'); 
                }
            });
         }
    });

    $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
        $rootScope.progressbar.complete();
        $rootScope.bodyClass = toState.bodyClass;
    });

    $rootScope.$on('$stateChangeError', function (event) {
        //$state.go('undefined');
    });
}]);

In service

    app.service('AuthService',['jwtHelper','$cookies','$location','$window','$http','$q',function (jwtHelper,$cookies,$location,$window,$http,$q) {

    this.login = function (token){
        var payload = jwtHelper.decodeToken(token);
    };

    this.logout = function (data) {

    };


var validatetoken = undefined;

this.checkPermission = function () {
    if (!validatetoken) {

        // create deferred object using $q
        var deferred = $q.defer();

        // get validatetoken form backend
        $http.post('/api/validatetoken', {token: $cookies.get('token')})
          .then(function(result) {
            // save fetched validatetoken to the local variable
            validatetoken = result.data;
            // resolve the deferred
            deferred.resolve(validatetoken);
          }, function(error) {
            validatetoken = error;
            deferred.reject(error);
          });
        // set the validatetoken object to be a promise until result comeback
        validatetoken = deferred.promise;
      }

      return $q.when(validatetoken);
}

    this.getFormInfo = function () {
         return $http.get("/api/getloginurl");
    }


}]);

1 Answer 1

1

i don't want to show jobs page initially for few seconds it should be redirect quickly or it will not load jobs page.

When using the ui-router, avoid putting code in the $locationChangeStart block. This will cause conflicts with ui-router operation.

To prevent the jobs page from loading, check the authorization in the resolver for the state.

$stateProvider.state("jobs", {
    url: "/jobs",
    templateUrl: "views/dashboard.html",
    controller: "JobController as JobCtrl",
    resolve : {
        formInfo : ["AuthService",function (AuthService) {
            return AuthService.getFormInfo();
        }],
        //CHECK permission
        permission: ["AuthService", function (AuthService) {
            return AuthService.checkPermission()
              .then(function(data) {
                if(!data.active){
                    return data 
                } else {
                    //REJECT if not authorized
                    throw "Not Authorized";
                };
            }).catch(function(error) {
                console.log("ERROR");
                throw error;
            });
        }];
    }
})

By rejecting the resolve, the state change will be aborted and the page will not load.


Update

I can put in resolve state but if we have more state for example we have 50 different URL then every time do we have to put permission:

["AuthService", function (AuthService) { 
       return AuthService.checkPermission() 
         .then( function(data) { 
           if(!data.active){ 
               return data
           } else { 
               //REJECT if not authorized throw "Not Authorized";
           }; 
       }).catch( function(error) { 
           console.log("ERROR");
           throw error;
       });

All of that code can be re-factored into a service:

app.service("permissionService",["AuthService", function (AuthService) { 
    this.get = function () {
       return AuthService.checkPermission() 
         .then( function(data) { 
           if(!data.active){ 
               return data
           } else { 
               //REJECT if not authorized 
               throw "Not Authorized";
           }; 
       }).catch( function(error) { 
           console.log("ERROR");
           throw error;
       });
    };
}]);

Then use it in each resolver:

        //CHECK permission
        permission: ["permissionService", function (permissionService) {
            return permissionService.get();
        }];

By re-factoring the code, the resolver can be greatly simplified.

Sign up to request clarification or add additional context in comments.

2 Comments

I can put in resolve state but if we have more state for example we have 50 different URL then every time do we have to put permission: ["AuthService", function (AuthService) { return AuthService.checkPermission() .then(function(data) { if(!data.active){ return data } else { //REJECT if not authorized throw "Not Authorized"; }; }).catch(function(error) { console.log("ERROR"); throw error; });
That code can be re-factored into a service.See update to answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.