yeoman, grunt 및 bower를 사용하여 만든 AngularJS 응용 프로그램이 있습니다.
인증을 확인하는 컨트롤러가있는 로그인 페이지가 있습니다. 신임 정보가 정확하면 홈페이지로 이동합니다.
app.js
'use strict';
//Define Routing for app
angular.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";
        }
    }
});
홈페이지에
<span class="user-info">
    <small>Welcome,</small>
    {{user.name}}
</span>
<span class="logout"><a href="" ng-click="logoutUser()">Logout</a></span>
에서 loginController, 나는 로그인 정보를 확인하고이 성공적이라면, 나는 서비스 공장에서 사용자 개체를 설정합니다. 이것이 올바른지 아닌지 모르겠습니다.
내가 필요한 것은 사용자가 로그인 할 때 다른 모든 페이지가 해당 값을 얻을 수 있도록 사용자 개체에 일부 값을 설정하는 것입니다.
경로 변경이 발생할 때마다 컨트롤러는 사용자가 로그인했는지 여부를 확인해야합니다. 그렇지 않은 경우 로그인 페이지로 다시 라우팅해야합니다. 또한 사용자가 이미 로그인하여 페이지로 돌아 오면 홈 페이지로 이동해야합니다. 또한 컨트롤러는 모든 경로에서 자격 증명을 확인해야합니다.
ng-cookies에 대해 들었지만 사용 방법을 모르겠습니다.
내가 본 많은 예는 명확하지 않았으며 일종의 액세스 역할이나 무언가를 사용합니다. 나는 그것을 원하지 않습니다. 로그인 필터 만 원합니다. 누군가 나에게 몇 가지 아이디어를 줄 수 있습니까?
답변
내 솔루션은 세 부분으로 나뉩니다. 사용자 상태는 서비스에 저장됩니다. 경로가 변경 될 때보 고 실행하는 방법으로 사용자가 요청한 페이지에 액세스 할 수 있는지 확인합니다. 사용자 변경 상태
app.run(['$rootScope', '$location', 'Auth', function ($rootScope, $location, Auth) {
    $rootScope.$on('$routeChangeStart', function (event) {
        if (!Auth.isLoggedIn()) {
            console.log('DENY');
            event.preventDefault();
            $location.path('/login');
        }
        else {
            console.log('ALLOW');
            $location.path('/home');
        }
    });
}]);
Auth사용자 개체를 처리하고 사용자의 로그 여부를 알 수있는 방법을 제공하는 서비스 (이름을 지정합니다 )를 만들어야합니다 .
서비스 :
 .factory('Auth', function(){
var user;
return{
    setUser : function(aUser){
        user = aUser;
    },
    isLoggedIn : function(){
        return(user)? user : false;
    }
  }
})
에서 이벤트를 app.run들어야합니다 $routeChangeStart. 경로가 변경되면 사용자가 기록되었는지 확인합니다 ( isLoggedIn방법이 처리해야 함). 사용자가 기록되지 않은 경우 요청 된 경로를로드하지 않고 사용자를 오른쪽 페이지 (사용자의 경우 로그인)로 리디렉션합니다.
는 loginController핸들 로그인에 로그인 페이지에 사용되어야한다. Auth서비스와 상호 작용 하고 사용자를 기록 된 상태로 설정해야합니다.
loginController :
.controller('loginCtrl', [ '$scope', 'Auth', function ($scope, Auth) {
  //submit
  $scope.login = function () {
    // Ask to the server, do your job and THEN set the user
    Auth.setUser(user); //Update the state of the user in the app
  };
}])
메인 컨트롤러에서 사용자 상태가 변경되면 수신하고 리디렉션에 반응 할 수 있습니다.
.controller('mainCtrl', ['$scope', 'Auth', '$location', function ($scope, Auth, $location) {
  $scope.$watch(Auth.isLoggedIn, function (value, oldValue) {
    if(!value && oldValue) {
      console.log("Disconnect");
      $location.path('/login');
    }
    if(value) {
      console.log("Connect");
      //Do something when the user is connected
    }
  }, true);
답변
또는의 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");
    });
  };
}])
답변
개별 경로에 대한 사용자 지정 동작을 정의하는 가장 간단한 방법은 매우 쉽습니다.
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(angular와의 충돌을 피하기 위해) 내부의 요소에 바인딩되지 않은 최상위 컨트롤러 에서 속성 이 $routeProvider있는지 확인 하고 그에 따라 행동하십시오.newUrlrequireAuth
 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");
         }
     });
 });
답변
나는 몇 달이 각도로 사용자 등록 및 로그인 기능을 설정하는 방법에 백업 게시물을 작성, 당신은 그것을 확인하실 수 있습니다 http://jasonwatmore.com/post/2015/03/10/AngularJS-User-Registration-and -Login-Example.aspx
사용자가 $locationChangeStart이벤트에 로그인했는지 확인하면 다음과 같은 주요 app.js가 표시됩니다.
(function () {
    'use strict';
 
    angular
        .module('app', ['ngRoute', 'ngCookies'])
        .config(config)
        .run(run);
 
    config.$inject = ['$routeProvider', '$locationProvider'];
    function config($routeProvider, $locationProvider) {
        $routeProvider
            .when('/', {
                controller: 'HomeController',
                templateUrl: 'home/home.view.html',
                controllerAs: 'vm'
            })
 
            .when('/login', {
                controller: 'LoginController',
                templateUrl: 'login/login.view.html',
                controllerAs: 'vm'
            })
 
            .when('/register', {
                controller: 'RegisterController',
                templateUrl: 'register/register.view.html',
                controllerAs: 'vm'
            })
 
            .otherwise({ redirectTo: '/login' });
    }
 
    run.$inject = ['$rootScope', '$location', '$cookieStore', '$http'];
    function run($rootScope, $location, $cookieStore, $http) {
        // keep user logged in after page refresh
        $rootScope.globals = $cookieStore.get('globals') || {};
        if ($rootScope.globals.currentUser) {
            $http.defaults.headers.common['Authorization'] = 'Basic ' + $rootScope.globals.currentUser.authdata; // jshint ignore:line
        }
 
        $rootScope.$on('$locationChangeStart', function (event, next, current) {
            // redirect to login page if not logged in and trying to access a restricted page
            var restrictedPage = $.inArray($location.path(), ['/login', '/register']) === -1;
            var loggedIn = $rootScope.globals.currentUser;
            if (restrictedPage && !loggedIn) {
                $location.path('/login');
            }
        });
    }
 
})();
답변
이 방법이 가장 쉬운 것처럼 느껴지지만 개인적인 취향 일뿐입니다.
로그인 경로 및 기타 익명 경로 (예 : / register, / logout, / refreshToken 등)를 지정할 때 다음을 추가하십시오.
allowAnonymous: true따라서 다음과 같은 것이 있습니다.
$stateProvider.state('login', {
    url: '/login',
    allowAnonymous: true, //if you move this, don't forget to update
                          //variable path in the force-page check.
    views: {
        root: {
            templateUrl: "app/auth/login/login.html",
            controller: 'LoginCtrl'
        }
    }
    //Any other config
}
“allowAnonymous : false”를 지정할 필요가 없습니다 (없는 경우). 대부분의 URL이 강제로 인증되는 앱에서는 작동이 줄어 듭니다. 그리고 더 안전합니다. 새 URL에 추가하는 것을 잊어 버린 경우 익명 URL이 보호되는 것이 최악입니다. “requireAuthentication : true”를 지정하여 다른 방법으로 URL을 추가하는 것을 잊어 버린 경우 민감한 페이지가 일반인에게 유출됩니다.
그런 다음 코드 디자인에 가장 적합한 곳이면 어디에서나 실행하십시오.
//I put it right after the main app module config. I.e. This thing:
angular.module('app', [ /* your dependencies*/ ])
       .config(function (/* you injections */) { /* your config */ })
//Make sure there's no ';' ending the previous line. We're chaining. (or just use a variable)
//
//Then force the logon page
.run(function ($rootScope, $state, $location, User /* My custom session obj */) {
    $rootScope.$on('$stateChangeStart', function(event, newState) {
        if (!User.authenticated && newState.allowAnonymous != true) {
            //Don't use: $state.go('login');
            //Apparently you can't set the $state while in a $state event.
            //It doesn't work properly. So we use the other way.
            $location.path("/login");
        }
    });
});
답변
app.js
'use strict';
// Declare app level module which depends on filters, and services
var app= angular.module('myApp', ['ngRoute','angularUtils.directives.dirPagination','ngLoadingSpinner']);
app.config(['$routeProvider', function($routeProvider) {
  $routeProvider.when('/login', {templateUrl: 'partials/login.html', controller: 'loginCtrl'});
  $routeProvider.when('/home', {templateUrl: 'partials/home.html', controller: 'homeCtrl'});
  $routeProvider.when('/salesnew', {templateUrl: 'partials/salesnew.html', controller: 'salesnewCtrl'});
  $routeProvider.when('/salesview', {templateUrl: 'partials/salesview.html', controller: 'salesviewCtrl'});
  $routeProvider.when('/users', {templateUrl: 'partials/users.html', controller: 'usersCtrl'});
    $routeProvider.when('/forgot', {templateUrl: 'partials/forgot.html', controller: 'forgotCtrl'});
  $routeProvider.otherwise({redirectTo: '/login'});
}]);
app.run(function($rootScope, $location, loginService){
    var routespermission=['/home'];  //route that require login
    var salesnew=['/salesnew'];
    var salesview=['/salesview'];
    var users=['/users'];
    $rootScope.$on('$routeChangeStart', function(){
        if( routespermission.indexOf($location.path()) !=-1
        || salesview.indexOf($location.path()) !=-1
        || salesnew.indexOf($location.path()) !=-1
        || users.indexOf($location.path()) !=-1)
        {
            var connected=loginService.islogged();
            connected.then(function(msg){
                if(!msg.data)
                {
                    $location.path('/login');
                }
            });
        }
    });
});
loginServices.js
'use strict';
app.factory('loginService',function($http, $location, sessionService){
    return{
        login:function(data,scope){
            var $promise=$http.post('data/user.php',data); //send data to user.php
            $promise.then(function(msg){
                var uid=msg.data;
                if(uid){
                    scope.msgtxt='Correct information';
                    sessionService.set('uid',uid);
                    $location.path('/home');
                }          
                else  {
                    scope.msgtxt='incorrect information';
                    $location.path('/login');
                }                  
            });
        },
        logout:function(){
            sessionService.destroy('uid');
            $location.path('/login');
        },
        islogged:function(){
            var $checkSessionServer=$http.post('data/check_session.php');
            return $checkSessionServer;
            /*
            if(sessionService.get('user')) return true;
            else return false;
            */
        }
    }
});
sessionServices.js
'use strict';
app.factory('sessionService', ['$http', function($http){
    return{
        set:function(key,value){
            return sessionStorage.setItem(key,value);
        },
        get:function(key){
            return sessionStorage.getItem(key);
        },
        destroy:function(key){
            $http.post('data/destroy_session.php');
            return sessionStorage.removeItem(key);
        }
    };
}])
loginCtrl.js
'use strict';
app.controller('loginCtrl', ['$scope','loginService', function ($scope,loginService) {
    $scope.msgtxt='';
    $scope.login=function(data){
        loginService.login(data,$scope); //call login service
    };
}]);
답변
당신은 사용할 수 있습니다 resolve:
angular.module('app',[])
.config(function($routeProvider)
{
    $routeProvider
    .when('/', {
        templateUrl  : 'app/views/login.html',
        controller   : 'YourController',
        controllerAs : 'Your',
        resolve: {
            factory : checkLoginRedirect
        }
    })
}
그리고 resolve의 기능 :
function checkLoginRedirect($location){
    var user = firebase.auth().currentUser;
    if (user) {
        // User is signed in.
        if ($location.path() == "/"){
            $location.path('dash'); 
        }
        return true;
    }else{
        // No user is signed in.
        $location.path('/');
        return false;
    }   
}
Firebase에는 관찰자를 설치하는 데 도움이되는 방법이 있습니다 .run.
.run(function(){
    firebase.auth().onAuthStateChanged(function(user) {
        if (user) {
            console.log('User is signed in.');
        } else {
            console.log('No user is signed in.');
        }
    });
  }