AngularJS-每个路由和控制器中的登录和身份验证

AngularJS-每个路由和控制器中的登录和身份验证

我有一个使用yeoman,grunt和bower创建的AngularJS应用程序。

我有一个登录页面,其中包含一个检查身份验证的控制器。如果凭据正确,我将重新路由到主页。

app.js

'use strict';//Define Routing for appangular.module('myApp', []).config(['$routeProvider', '$locationProvider',
  function($routeProvider,$locationProvider) {
    $routeProvider    .when('/login', {
        templateUrl: 'login.html',
        controller: 'LoginController'
    })
    .when('/register', {
        templateUrl: 'register.html',
        controller: 'RegisterController'
      })
    .when('/forgotPassword', {
        templateUrl: 'forgotpassword.html',
        controller: 'forgotController'
      })
   .when('/home', {
       templateUrl: 'views/home.html',
       controller: 'homeController'
    })
    .otherwise({
       redirectTo: '/login'
    });//    $locationProvider.html5Mode(true); //Remove the '#' from URL.}]);angular.module('myApp').factory("page", function($rootScope){
    var page={};
    var user={};
    page.setPage=function(title,bodyClass){
        $rootScope.pageTitle = title;
        $rootScope.bodylayout=bodyClass;
    };
    page.setUser=function(user){
        $rootScope.user=user;
    }
    return page;});

LoginControler.js

'use strict';angular.module('myApp').controller('LoginController', function($scope, $location, $window,page) {
    page.setPage("Login","login-layout");
    $scope.user = {};
    $scope.loginUser=function()
    {
        var username=$scope.user.name;
        var password=$scope.user.password;
        if(username=="admin" && password=="admin123")
        {
            page.setUser($scope.user);
            $location.path( "/home" );
        }
        else
        {
            $scope.message="Error";
            $scope.messagecolor="alert alert-danger";
        }
    }});


loginController,我检查登录信息,如果成功,我在服务工厂设置用户对象。我不知道这是否正确。

我需要的是,当用户登录时,它在用户对象中设置一些值,以便所有其他页面都可以获得该值。

无论何时发生任何路由更改,控制器都应检查用户是否已登录。如果没有,它应该重新路由到登录页面。此外,如果用户已登录并返回页面,则应转到主页。控制器还应检查所有路由上的凭据。

我听说过ng-cookies,但我不知道如何使用它们。

我看到的许多例子都不是很清楚,他们使用某种访问角色或其他东西。我不希望这样。我只想要一个登录过滤器。有人可以给我一些想法吗?


冉冉说
浏览 806回答 3
3回答

慕运维8079593

这是另一种可能的解决方案,使用或的resolve属性。示例:$stateProvider$routeProvider$stateProvider.config(["$stateProvider", function ($stateProvider) {   $stateProvider  .state("forbidden", {     /* ... */   })   .state("signIn", {     /* ... */     resolve: {       access: ["Access", function (Access) { return Access.isAnonymous(); }],     }   })   .state("home", {     /* ... */     resolve: {       access: ["Access", function (Access) { return Access.isAuthenticated(); }],     }   })   .state("admin", {     /* ... */     resolve: {       access: ["Access", function (Access) { return Access.hasRole("ROLE_ADMIN"); }],     }   });}])Access 根据当前用户权限解析或拒绝承诺:.factory("Access", ["$q", "UserProfile", function ($q, UserProfile) {   var Access = {     OK: 200,     // "we don't know who you are, so we can't say if you're authorized to access     // this resource or not yet, please sign in first"     UNAUTHORIZED: 401,     // "we know who you are, and your profile does not allow you to access this resource"     FORBIDDEN: 403,     hasRole: function (role) {       return UserProfile.then(function (userProfile) {         if (userProfile.$hasRole(role)) {           return Access.OK;         } else if (userProfile.$isAnonymous()) {           return $q.reject(Access.UNAUTHORIZED);         } else {           return $q.reject(Access.FORBIDDEN);         }       });     },     hasAnyRole: function (roles) {       return UserProfile.then(function (userProfile) {         if (userProfile.$hasAnyRole(roles)) {           return Access.OK;         } else if (userProfile.$isAnonymous()) {           return $q.reject(Access.UNAUTHORIZED);         } else {           return $q.reject(Access.FORBIDDEN);         }       });     },     isAnonymous: function () {       return UserProfile.then(function (userProfile) {         if (userProfile.$isAnonymous()) {           return Access.OK;         } else {           return $q.reject(Access.FORBIDDEN);         }       });     },     isAuthenticated: function () {       return UserProfile.then(function (userProfile) {         if (userProfile.$isAuthenticated()) {           return Access.OK;         } else {           return $q.reject(Access.UNAUTHORIZED);         }       });     }   };   return Access;}])UserProfile将当前用户的属性,并执行$hasRole,$hasAnyRole,$isAnonymous和$isAuthenticated方法的逻辑(加上一个$refresh方法,稍后解释):.factory("UserProfile", ["Auth", function (Auth) {   var userProfile = {};   var clearUserProfile = function () {     for (var prop in userProfile) {       if (userProfile.hasOwnProperty(prop)) {         delete userProfile[prop];       }     }   };   var fetchUserProfile = function () {     return Auth.getProfile().then(function (response) {       clearUserProfile();       return angular.extend(userProfile, response.data, {         $refresh: fetchUserProfile,         $hasRole: function (role) {           return userProfile.roles.indexOf(role) >= 0;         },         $hasAnyRole: function (roles) {           return !!userProfile.roles.filter(function (role) {             return roles.indexOf(role) >= 0;           }).length;         },         $isAnonymous: function () {           return userProfile.anonymous;         },         $isAuthenticated: function () {           return !userProfile.anonymous;         }       });     });   };   return fetchUserProfile();}])Auth 负责请求服务器,知道用户配置文件(例如链接到附加到请求的访问令牌):.service("Auth", ["$http", function ($http) {   this.getProfile = function () {     return $http.get("api/auth");   };}])在请求时,服务器应返回此类JSON对象GET api/auth:{   "name": "John Doe", // plus any other user information   "roles": ["ROLE_ADMIN", "ROLE_USER"], // or any other role (or no role at all, i.e. an empty array)   "anonymous": false // or true}最后,当Access拒绝承诺时,如果使用ui.router,$stateChangeError则会触发该事件:.run(["$rootScope", "Access", "$state", "$log", function ($rootScope, Access, $state, $log) {   $rootScope.$on("$stateChangeError", function (event, toState, toParams, fromState, fromParams, error) {     switch (error) {     case Access.UNAUTHORIZED:       $state.go("signIn");       break;     case Access.FORBIDDEN:       $state.go("forbidden");       break;     default:       $log.warn("$stateChangeError event catched");       break;     }   });}])如果使用ngRoute,$routeChangeError将触发该事件:.run(["$rootScope", "Access", "$location", "$log", function ($rootScope, Access, $location, $log) {   $rootScope.$on("$routeChangeError", function (event, current, previous, rejection) {     switch (rejection) {     case Access.UNAUTHORIZED:       $location.path("/signin");       break;     case Access.FORBIDDEN:       $location.path("/forbidden");       break;     default:       $log.warn("$stateChangeError event catched");       break;     }   });}])也可以在控制器中访问用户配置文件:.state("home", {   /* ... */   controller: "HomeController",   resolve: {     userProfile: "UserProfile"   }})UserProfile然后包含服务器在请求时返回的属性GET api/auth:.controller("HomeController", ["$scope", "userProfile", function ($scope, userProfile) {   $scope.title = "Hello " + userProfile.name; // "Hello John Doe" in the example}])UserProfile需要在用户登录或注销时刷新,以便Access可以使用新的用户配置文件处理路由。您可以重新加载整个页面,也可以调用UserProfile.$refresh()。登录时的示例:.service("Auth", ["$http", function ($http) {   /* ... */   this.signIn = function (credentials) {     return $http.post("api/auth", credentials).then(function (response) {       // authentication succeeded, store the response access token somewhere (if any)     });   };}]).state("signIn", {   /* ... */   controller: "SignInController",   resolve: {     /* ... */     userProfile: "UserProfile"   }}).controller("SignInController", ["$scope", "$state", "Auth", "userProfile", function ($scope, $state, Auth, userProfile) {   $scope.signIn = function () {     Auth.signIn($scope.credentials).then(function () {       // user successfully authenticated, refresh UserProfile       return userProfile.$refresh();     }).then(function () {       // UserProfile is refreshed, redirect user somewhere       $state.go("home");     });   };}])

慕桂英3389331

为各个路由定义自定义行为的最简单方法相当简单:1)routes.js:requireAuth为任何所需的路线创建一个新属性(如)angular.module('yourApp').config(function($routeProvider) {     $routeProvider        .when('/home', {             templateUrl: 'templates/home.html',             requireAuth: true // our custom property         })         .when('/login', {             templateUrl: 'templates/login.html',         })         .otherwise({             redirectTo: '/home'         });})2)在未绑定到内部元素的顶层控制器中ng-view(为避免与角度冲突$routeProvider),检查是否newUrl具有requireAuth属性并相应地采取相应措施 angular.module('YourApp').controller('YourController', function ($scope, $location, session) {      // intercept the route change event      $scope.$on('$routeChangeStart', function (angularEvent, newUrl) {          // check if the custom property exist          if (newUrl.requireAuth && !session.user) {              // user isn’t authenticated              $location.path("/login");          }      });  });
打开App,查看更多内容
随时随地看视频慕课网APP