AngularJS检查每条路线的用户状态

时间:2015-03-06 12:10:59

标签: angularjs

我是角色的新手,但我设法创建了一个应用程序并设法实现了一个如下所示的登录解决方案:

angular.module('app.security', ['ngRoute', 'ngTouch'])

// ---
// ROUTES.
// ---

.config(function ($routeProvider) {
    $routeProvider.when('/security/login', {
        templateUrl: '/app/security/security.tpl.html'
    })
    .when('/security/logout', {
        resolve: {
            logout: ['$location', 'AuthService', function ($location, authService) {
                console.log(authService);

                authService.logout();
                $location.path('/security/login');
                $location.replace();
            }]
        }
    });
})

// ---
// CONTROLLERS.
// ---

.controller('LoginController', ['AuthService', '$location',
    function (authService, $location) {
        var self = this;

        self.user = { userName: '', password: '' };

        self.login = function () {
            authService.login(self.user).then(function (success) {
                $location.path('/');
            }, function (error) {
                self.errorMessage = (error) ? error.error_description : 'There was a serious error when attempting to login. Please contact an administrator.';
            })
        };
    }
])

// ---
// SERVICES.
// ---

.factory('AuthService', ['apiUrl', '$http', '$q', function (api, $http, $q) {
    var _authentication = {
        isAuthenticated: false,
        userName: ""
    };

    var _login = function (loginData) {
        var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password;
        var deferred = $q.defer();

        $http.post(api + 'token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } })
            .success(function (response) {
                sessionStorage.authorizationData = angular.toJson({ token: response.access_token, userName: loginData.userName });

                _authentication.isAuthenticated = true;
                _authentication.userName = loginData.userName;

                deferred.resolve(response);
            }).error(function (err, status) {
                _logOut();

                deferred.reject(err);
            });

        return deferred.promise;
    };

    var _logout = function () {
        sessionStorage.removeItem('authorizationData');
        _authentication.isAuthenticated = false;
        _authentication.userName = "";
    };

    var _init = function () {
        var authData = angular.fromJson(sessionStorage.authorizationData);

        if (authData) {
            _authentication.isAuthenticated = true;
            _authentication.userName = authData.userName;
        }
    };

    _init(); // Constructor

    var service = {};

    service.login = _login;
    service.logout = _logout;
    service.authentication = _authentication;

    return service;
}])

.factory('AuthInterceptorService', ['$q', '$location', function ($q, $location) {
    var _request = function (config) {
        var authData = angular.fromJson(sessionStorage.authorizationData);

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

        if (authData) {
            config.headers.Authorization = 'Bearer ' + authData.token;
        }

        return config;
    }

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

    var authInterceptorServiceFactory = {};

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

    return authInterceptorServiceFactory;
}]);

这一切都很好,我对结果很满意。如您所见,每当我发出API请求时,拦截器都会检查我是否有 authData ,如果我这样做,它会提供 accessToken 以及API请求。 如果我没有并且有401错误,那么我将被重定向到登录页面。 太棒了:))

但我想做的是,第一页加载时检查是否存在 authData ,以及它是否未重定向到登录页面。 这样做的最佳方式是什么?

如果您需要更多信息,请告诉我,我不想用不必要的代码轰炸这个问题。

1 个答案:

答案 0 :(得分:0)

您可以使用路由器的$ stateChangeStart事件。当用户没有进入时,您可以将用户重定向到登录页面。

app.run(['$rootScope', '$exceptionHandler', '$state', 'AuthService',
function ($rootScope, $exceptionHandler, $state, AuthService) {

    $rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {

        // abort the state request when user is not authenticated
        if (!AuthService.isAuthentificated && toState.authentication !== "none") {
            event.preventDefault();

            // try if we could auto login the user cookie
            Authentication.autoLoginUserFromCookie().then(
                function success (respons) {
                    // continue with the requested state
                    $state.go(toState.name);
                },
                function fail (error) {
                    // no (valid) cookie
                    $state.go("login");
                }
            );
        }

    });
}]);

在州提供者中,我为每个州添加了“身份验证”属性

$stateProvider

            .state('login', {
                url: '/login',
                templateUrl: 'login.html'
                authentication : 'none'
            })
            .state('dashboard', {
                url: '/dashboard',
                templateUrl: 'dashboard.html'
                authentication : 'user'
            })
    }]);