1

我正在使用git采用的Angular web应用程序模板。我不明白一个功能,我想,验证用户是否有授权。不是吗?我的目标是有一个功能,使登录。采取响应并保存令牌。然后,当$状态改变时,检查是否还有令牌。我能怎么做?这是代码:在Angular中授权检查访问

core.js:

'use strict'; 

angular.module('app.core').controller('App', ['config', '$scope', '$state', '$rootScope', 'shortHistory','session', '$window', 'authorize', function(config, $scope, $state, $rootScope, shortHistory, session, $window, 'authorize') { 

var vm = this; 

vm.title = config.appTitle; 

$scope.app = config; 
$scope.$state = $state; 
vm.currentUser = null; 

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

$scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams) { 
    $('body').toggleClass('nav-shown', false); 
}); 

$rootScope.$on('$userSet', function(event, user) { 
    vm.currentUser = user; 
    $window.localStorage.setItem('token', vm.currentUser.token); 
}); 

shortHistory.init($scope); 

}]); 

common.js:

(function() { 
'use strict'; 

angular.module('app.common') 
    .service('shortHistory', shortHistory) 
    .service('session', session) 
// .service('authorize', authorize) 
    .service('authenticationService', authenticationService); 

shortHistory.$inject = ['$state']; 
function shortHistory($state) { 
    var history = this; 

    function setItem(what, state, params) { 
    history[what] = { 
     state: state, 
     params: params 
    }; 
    } 

    this.init = function(scope) { 
    scope.$on('$stateChangeSuccess', function(event, toState, toParams, fromState, fromParams){ 
     setItem('from', fromState, fromParams); 
     setItem('to', toState, toParams); 
    }); 
    }; 

    this.goTo = function(where) { 
    $state.go(history[where].state.name, history[where].params) 
    }; 
} 

session.$inject = ['$http', '$q', '$rootScope']; 
function session($http, $q, $rootScope) { 
    var session = this; 

    this.fetchCurrentUser = function(url) { 
    var userFetch; 
    if (session.getCurrentUser()) { 
     userFetch = $q(function(resolve) { 
     resolve(session.getCurrentUser()); 
     }); 
    } else { 
     userFetch = $http.get(url); 
    } 
    return userFetch; 
    }; 

    this.getCurrentUser = function() { 
    return this.user; 
    }; 

    this.setCurrentUser = function(user) { 
    this.user = user; 
    $rootScope.$broadcast('$userSet', this.user); 
    }; 
} 
/* THIS IS THE CODE THAT I'VE NOT TOUCHED, IT WAS IN THE TEMPLATE 
authorize.$inject = ['session', '$state', '$urlRouter', '$rootScope']; 
function authorize(session, $state, $rootScope) { 
    this.checkAccess = function(event, toState, toParams) { 
    if (!session.getCurrentUser() && !(toState.data && toState.data.noAuth)) { 
     event.preventDefault(); 
     session.fetchCurrentUser('api/sers') 
     .success(function(user) { 
      session.setCurrentUser(user); 
      $state.go(toState.name, toParams); 
     }) 
     .error(function() { 
      $state.go('login'); 
     }); 
     } 
    }; 
} 
*/ 
authenticationService.$inject = ['$http', '$rootScope', 'session', '$state']; 
function authenticationService($http, $rootScope, session) { 
    var vm = this; 
    vm.loginError = ''; 
    this.login = function(user) { 
    var userData = { 
     email: user.email, 
     password: user.password 
    } 
    return $http.post('api/login/', userData) 
     .success(function(data) { 
     var loggedUser = jQuery.extend(data, userData); 
     session.setCurrentUser(loggedUser); 
     $rootScope.$broadcast('$userLoggedIn'); 
     }); 
    }; 

    var token = localStorage.getItem('token'); 

    this.logout = function() { 
    return $http.post('api/logout/', token) 
     .success(function(data) { 
     session.setCurrentUser(null); 
     $rootScope.$broadcast('$userLoggedOut'); 
     }); 
    } 
} 

})(); 

Auth.js:

(function() { 
'use strict'; 

angular.module('app.profile') 
    .controller('LoginController', loginController) 
    .run(runAuth); 

loginController.$inject = ['authenticationService']; 
function loginController(
    authenticationService 
) { 
    var vm = this; 
    vm.user = {}; 
    vm.loginError = ''; 

    this.login = function() { 
    authenticationService.login(vm.user) 
     .then(null, function(err) { 
     vm.loginError = err.data.result; 
     }); 
    }; 
} 

runAuth.$inject = ['$rootScope', '$state', 'authenticationService']; 
function runAuth($rootScope, $state, authenticationService) { 
    $rootScope.logout = authenticationService.logout; 
    $rootScope.$on('$userLoggedIn', function() { 
    $state.go('app.dashboard'); 
    }); 
    $rootScope.$on('$userLoggedOut', function() { 
    $state.go('login'); 
    }); 
} 
})(); 

profile.module.js:

'use strict'; 

angular.module( 'app.profile',[ 'ui.router'])

.config(['$stateProvider', function($stateProvider) { 
    $stateProvider 
    .state('login', { 
     url: '/login', 
     data: { 
     noAuth: true 
     }, 
     templateUrl: 'app/modules/profile/auth/login.html', 
     controller: 'LoginController', 
     controllerAs: 'vm' 
    }) 
    .state('app.profile', { 
     url: '/profile', 
     templateUrl: 'app/modules/profile/edit/edit.html', 
     controller: 'ProfileController', 
     controllerAs: 'vm' 
    }); 
    }]); 

原来的项目是这样的:https://github.com/flatlogic/angular-dashboard-seed 我不明白怎么验证工作,并在那里插入控制器进行身份验证。例如,现在,我无法登录,但无法执行注销,即使没有令牌,我也可以正确转到/仪表板或/配置文件,该配置文件只应由已登录的用户查看。

回答

0

你在这里有很多代码,但我觉得你的问题可以在理论上回答得比使用更多的代码!

  • 使用您的后端服务器设置会话信息(通常是HTTP标头中的cookie),然后不要在AngularJS代码中进行任何本地操作。我看到您正在检查本地存储的某些区域。它更容易,更安全,只是让后端设置HTTP唯一标志true并围绕构建应用程序逻辑,不知道会话ID
  • 利用拦截重定向401个Ajax请求到您的登录页面。这将允许你来处理会话超时,未授权的访问路径,等等。一个非常简单的处理程序,它会简单的多重定向逻辑https://docs.angularjs.org/api/ng/service/ $ HTTP#拦截
  • 根据你的路由的实例(看来您正在使用UI路由器)您可以根据您的身份验证服务返回的用户来管理特定路由的权限。我遇到的最干净的实现利用了UI路由器和嵌套状态。需要身份验证的状态具有配置的根“resolve”参数,用于执行用户会话的验证(可能只是简单的HTTP GET到受保护的端点以确定用户是否已通过身份验证)。当你需要知道在任何给定的控制器的用户,你会真正体会到这个架构,你可以随时知道你的用户服务已经有一个想通了(没必要依靠广播)

例如:

$stateProvider 
    .state('rootProtected', { 
    templateUrl: '/js/views/rootProtected.html', 
    resolve: { 
     data: function(coreuser) { 
     return user.initialize(); 
     } 
    } 
    }) 
    .state('rootProtected.userProfile', { 
    templateUrl: '/js/views/userProfile.html' 
    }) 
    .state('public', { 
    templateUrl: '/js/views/login.html' 
    }); 
  • 尽量不要在会话管理周围创建太多的服务/工厂。我在遍布互联网的教程中看到了这一点。真的,只需创建一个核心用户服务来记录用户,注销用户,验证用户,获取用户等等。您将开始意识到大量数据是相互关联的,并且没有理由将逻辑分散多种服务或广播事件。