Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

EDIT: forgot to mention that i've been working with AngularJs for a week only, so if you see something you think should be changed for the better and is not related to the question itself feel free to tell me on the comments section.


ok, so I have my authentication Controllers and providers which I won't show because they're irrelevant for the scope of the question. Then I have an interceptor to check if the user is authenticated when a Call is made. If so I set the Authentication header on the request to include the user's Token if not I redirect the user to the login page and don't even make the request to the server (obviously if someone bypasses this theres also an Authorize on the API).

What I want is to add a few exceptions, meaning there are some pages I want to allow even if the user has no Auth Token. I'm able to this if it's a specific path, but I want to allow my 404 page to be accessed and it's in the Routing that I'm specifying .otherwise to go to the 404 page, how can I make so that my interceptor only redirects to login if it's not going to this page.

The interceptor

.factory('authInterceptorService', ['$q', '$location', 'localStorageService', function ($q, $location, localStorageService) {

    var authInterceptorServiceFactory = {};

    var authData = localStorageService.get('authorizationData');

    var _request = function (config) {

        config.headers = config.headers || {};

        if (authData) {
            config.headers.Authorization = 'Bearer ' + authData.token;
        } else if ($location.path != '/accounts/login' && $location.path != '/accounts/register') {
            $location.path('/accounts/login');
        }

        return config;
    }

    var _responseError = function (rejection) {
        if (rejection.status === 401) {
            $location.path('/accounts/login');
        }
        return $q.reject(rejection);
    }

    authInterceptorServiceFactory.request = _request;
    authInterceptorServiceFactory.responseError = _responseError;

    return authInterceptorServiceFactory;
}])

and in my Routing

 $urlRouterProvider.otherwise('/page-not-found');

 $stateProvider
     (...)//rest of the states

     .state('page-not-found', {
         url: '/page-not-found',
         templateUrl: '/Content/partials/error/404.html',
         data: {
             displayName: false
         }
     })

     (...)//rest of the states

I tried to add '/page-not-found' to my if but it won't work as expected because by the time the location is checked for the first time it's still not redirected.

edit As sugested by charlietfl I'm now trying to use resolve but it's not even passing my function.

I removed this code from my interceptor:

else if ($location.path != '/accounts/login' && $location.path != '/accounts/register') {
    $location.path('/accounts/login');
}

and add a new service to the authentication module:

.service('authCheckService', ['$http', '$q', 'localStorageService', function ($http, $q, localStorageService) {
    var self = {
        'onlyLoggedIn': function ($state, $q) {
            var deferred = $q.defer();
            var authData = localStorageService.get('authorizationData');
            console.log(authData);
            if (authData) {
                deferred.resolve();
            } else {
                deferred.reject();
                $state.go('login');
            }
            return deferred.promise;
        }
    }

    return self;
}]);

and i'm trying to call it as:

.state('smo-dashboard', {
        url: '/dashboard',
        templateUrl: '/Content/partials/dashboard.html',
        resolve: authCheckServiceProvider.onlyLoggedIn
})

notice that i'm trying to log authData var to check if it's working but it isn't and there's no error on the console also.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
677 views
Welcome To Ask or Share your Answers For Others

1 Answer

Finally figured out how to solve it using resolve.

first of all I completely removed the interceptor I was using before. then I made a function inside my Routing .config to use with every resolve for the authentication. finally to handle my resolve I'm using $stateChangeError to redirect to the login state

the Routing Config

.config(function ($stateProvider, $urlRouterProvider) {

    // function to check the authentication //
    var Auth = ["$q", "authService", function ($q, authService) {
        authService.fillAuthData;
        if (authService.authentication.isAuth) {
            return $q.when(authService.authentication);
        } else {
            return $q.reject({ authenticated: false });
        }
    }];

    /* if the state does not exist */
    $urlRouterProvider
        .otherwise('/page-not-found'); 

    $stateProvider

        // state that allows non authenticated users //
        .state('home', {
            url: '/',
            templateUrl: '/Content/partials/home.html',
        })

        // state that needs authentication //
        .state('smo-dashboard', {
            url: '/dashboard',
            templateUrl: '/Content/partials/dashboard.html',
            resolve: {
                auth: Auth
            }
        })

        // errors //
         .state('page-not-found', {
             url: '/page-not-found',
             templateUrl: '/Content/partials/error/404.html'
         })

        // accounts //
        .state('login', {
            url: '/accounts/login',
            templateUrl: '/Content/partials/account/login.html'
        })

        // OTHER STATES //
    }
);

in the MainController

$scope.$on("$stateChangeError", function (event, toState, toParams, fromState, fromParams, error) {
    $state.go("login");
});

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...