【问题标题】:Authorize check access in Angular在 Angular 中授权检查访问
【发布时间】:2023-03-23 18:19:01
【问题描述】:

我正在使用 git 采用的 Angular Web 应用程序模板。我无法理解我想验证用户是否具有授权的功能。不是吗?我的目标是拥有一个登录功能。获取响应并保存令牌。然后,当 $state 发生变化时,检查是否还有令牌。我能怎么做?这是代码:

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 我无法理解该身份验证的工作原理以及在何处插入控制器进行身份验证。例如,现在,我无法登录但无法注销,即使我没有令牌,我也可以正确转到 /dashboard,或 /profile,应该由登录用户查看。

【问题讨论】:

    标签: javascript angularjs http xmlhttprequest angular-http-interceptors


    【解决方案1】:

    你这里有相当多的代码,但我觉得你的问题可以比更多的代码更理论上得到回答!

    • 使用后端服务器设置会话信息(通常是 HTTP 标头中的 cookie),然后不要在 AngularJS 代码中进行任何本地操作。我看到您正在检查本地存储的某些区域。让后端将仅 HTTP 标志设置为 true 并在不知道会话 ID 的情况下构建您的应用程序逻辑会更容易、更安全
    • 利用拦截将 401 ajax 请求重定向到您的登录页面。这将允许您处理会话超时、未经授权的路由访问等实例。一个非常简单的处理程序,它将简单地处理大部分重定向逻辑 https://docs.angularjs.org/api/ng/service/$http#interceptors
    • 根据您的路由(您似乎正在使用 UI 路由器),您可以根据从您的身份验证服务返回的用户来管理对特定路由的权限。我遇到的最简洁的实现使用了 UI 路由器和嵌套状态。需要身份验证的状态具有配置的根“解析”参数,该参数执行用户会话的验证(可能只是对受保护端点的简单 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'
      });
    
    • 尽量不要围绕会话管理创建过多的服务/工厂。我在互联网上的教程中看到了这一点。真的,只需创建一个核心用户服务,让用户登录、注销用户、验证用户、获取用户等。您将开始意识到很多数据是相互关联的,没有理由将逻辑分散在其中多种服务或广播事件。

    【讨论】:

      猜你喜欢
      • 2017-11-29
      • 2016-03-14
      • 2018-09-11
      • 1970-01-01
      • 1970-01-01
      • 2020-11-23
      • 2013-09-05
      • 2017-05-24
      • 1970-01-01
      相关资源
      最近更新 更多