AngularJS- Đăng nhập và xác thực trong từng tuyến và bộ điều khiển


130

Tôi có một ứng dụng AngularJS được tạo bằng cách sử dụng yeoman, grunt và bower.

Tôi có một trang đăng nhập có bộ điều khiển kiểm tra xác thực. Nếu thông tin đăng nhập đúng, tôi định tuyến lại trang chủ.

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;
});

Đăng nhậpControler.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";
        }
    }
});

Trên trang chủ tôi có

<span class="user-info">
    <small>Welcome,</small>
    {{user.name}}
</span>
<span class="logout"><a href="" ng-click="logoutUser()">Logout</a></span>

Trong phần loginController, tôi kiểm tra thông tin đăng nhập và nếu thành công, tôi đặt đối tượng người dùng trong nhà máy dịch vụ. Tôi không biết điều này có đúng hay không.

Điều tôi cần là, Khi người dùng đăng nhập, Nó đặt một số giá trị trong đối tượng người dùng để tất cả các trang khác có thể nhận được giá trị đó.

Bất cứ khi nào có thay đổi tuyến đường xảy ra, bộ điều khiển nên kiểm tra xem người dùng có đăng nhập hay không. Nếu không, nó sẽ định tuyến lại đến trang đăng nhập. Ngoài ra, nếu người dùng đã đăng nhập và quay lại trang, nó sẽ đi đến trang chủ. Bộ điều khiển cũng nên kiểm tra thông tin đăng nhập trên tất cả các tuyến.

Tôi đã nghe nói về ng-cookies, nhưng tôi không biết cách sử dụng chúng.

Nhiều ví dụ tôi thấy không rõ ràng lắm và họ sử dụng một số loại vai trò truy cập hoặc một cái gì đó. Tôi không muốn điều đó. Tôi chỉ muốn một bộ lọc đăng nhập. Ai đó có thể cho tôi một số ý tưởng?

Câu trả lời:


180

Giải pháp của tôi được chia thành 3 phần: trạng thái của người dùng được lưu trữ trong một dịch vụ, trong phương thức chạy bạn xem khi tuyến đường thay đổi và bạn kiểm tra xem người dùng có được phép truy cập trang được yêu cầu hay không, trong bộ điều khiển chính của bạn, bạn xem nếu trạng thái của người dùng thay đổi.

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');
        }
    });
}]);

Bạn nên tạo một dịch vụ (tôi sẽ đặt tên cho nó Auth) sẽ xử lý đối tượng người dùng và có một phương thức để biết người dùng có đăng nhập hay không.

dịch vụ :

 .factory('Auth', function(){
var user;

return{
    setUser : function(aUser){
        user = aUser;
    },
    isLoggedIn : function(){
        return(user)? user : false;
    }
  }
})

Từ bạn app.run, bạn nên lắng nghe $routeChangeStartsự kiện. Khi tuyến đường sẽ thay đổi, nó sẽ kiểm tra xem người dùng có đăng nhập không ( isLoggedInphương thức sẽ xử lý nó). Nó sẽ không tải tuyến được yêu cầu nếu người dùng chưa đăng nhập và nó sẽ chuyển hướng người dùng đến đúng trang (trong trường hợp đăng nhập của bạn).

Các loginControllernên được sử dụng trong trang đăng nhập của bạn để xử lý đăng nhập. Nó chỉ nên can thiệp vào Authdịch vụ và đặt người dùng là đăng nhập hay không.

loginControll :

.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
  };
}])

Từ bộ điều khiển chính của bạn, bạn có thể lắng nghe nếu trạng thái người dùng thay đổi và phản ứng với chuyển hướng.

.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);

1
Trình đăng nhập sẽ cho phép người dùng đăng nhập từ trang đăng nhập. Nó sẽ xử lý các hình thức đăng nhập. Biểu mẫu phải gọi một phương thức gửi là một phần của loginContoder của bạn. Phương pháp này sẽ cập nhật (nếu biểu mẫu là chính xác và người dùng phải đăng nhập) trạng thái của người dùng SỬ DỤNG dịch vụ Auth mà tôi đã mô tả.
gab

2
Làm việc như người ở! Thay vì dịch vụ được cung cấp, tôi đã sử dụng Auth0 với AngularJS .
Nikos Baxevanis

34
Nếu người dùng nhấn F5 và làm mới thì sao? Sau đó, bộ nhớ trong Auth của bạn đã biến mất.
Gaui

4
Chỉ trong trường hợp những người khác gặp sự cố khi chạy ví dụ này: trong cuộc routeChangeStartgọi lại, bạn nên kiểm tra xem vị trí có thực sự là "/ đăng nhập" hay không và cho phép:if ( $location.path() === "/login" ) return;
user2084865

1
nó đưa tôi vào vòng lặp vô hạn.
Nipun Tyagi

110

Đây là một giải pháp khả thi khác, sử dụng resolve thuộc tính của $stateProviderhoặc $routeProvider. Ví dụ với $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 giải quyết hoặc từ chối lời hứa tùy thuộc vào quyền người dùng hiện tại:

.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 sao chép các thuộc tính người dùng hiện tại và thực hiện $hasRole , $hasAnyRole, $isAnonymous$isAuthenticatedphương pháp logic (cộng với một $refreshphương pháp, giải thích sau):

.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 chịu trách nhiệm yêu cầu máy chủ, để biết hồ sơ người dùng (được liên kết với mã thông báo truy cập được đính kèm với yêu cầu chẳng hạn):

.service("Auth", ["$http", function ($http) {

  this.getProfile = function () {
    return $http.get("api/auth");
  };

}])

Máy chủ dự kiến ​​sẽ trả về một đối tượng JSON như vậy khi yêu cầu 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
}

Cuối cùng, khi nào Access từ chối một lời hứa, nếu sử dụng ui.router, $stateChangeErrorsự kiện sẽ bị hủy:

.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;

    }
  });

}])

Nếu sử dụng ngRoute , $routeChangeErrorsự kiện sẽ bị hủy:

.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;

    }
  });

}])

Hồ sơ người dùng cũng có thể được truy cập trong bộ điều khiển:

.state("home", {
  /* ... */
  controller: "HomeController",
  resolve: {
    userProfile: "UserProfile"
  }
})

UserProfile sau đó chứa các thuộc tính được máy chủ trả về khi yêu cầu GET api/auth :

.controller("HomeController", ["$scope", "userProfile", function ($scope, userProfile) {

  $scope.title = "Hello " + userProfile.name; // "Hello John Doe" in the example

}])

UserProfilecần được làm mới khi người dùng đăng nhập hoặc đăng xuất, để Accesscó thể xử lý các tuyến đường với hồ sơ người dùng mới. Bạn có thể tải lại toàn bộ trang hoặc gọi UserProfile.$refresh(). Ví dụ khi đăng nhập:

.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");
    });
  };

}])

3
Tôi nghĩ rằng đây là câu trả lời đơn giản nhất và cũng có thể mở rộng nhất
Jotham

2
@LeblancMeneses Cảm ơn :) Chỉ cần nói rõ hơn: UNAUTHORIZED có nghĩa là "chúng tôi không biết bạn là ai, vì vậy chúng tôi không thể nói nếu bạn được phép truy cập tài nguyên này hay chưa, vui lòng đăng nhập trước" , trong khi FORBIDDEN có nghĩa là "chúng tôi biết bạn là ai và hồ sơ của bạn không cho phép bạn truy cập tài nguyên này" .
sp00m

1
Giải pháp hay, phù hợp tiềm năng với xác thực Spring ở phía máy chủ
Jan Peter

1
Giải pháp tốt nhất từ ​​trước đến nay!
Renan Franca

1
@jsbisht Tất cả phụ thuộc vào nơi bạn lưu trữ mã thông báo truy cập (xem đoạn trích cuối). Nếu bạn chỉ lưu trữ nó trong bộ nhớ JS, thì có: F5 sẽ xóa thông tin xác thực. Nhưng nếu bạn lưu trữ nó trong một bộ lưu trữ liên tục (ví dụ: cookie / localStorage / sessionStorage), thì không: F5 sẽ không xóa thông tin xác thực (miễn là bạn đính kèm mã thông báo cho mỗi yêu cầu $ http, hoặc ít nhất là với các yêu cầu được gửi đến phần còn lại / người dùng / hồ sơ, vì máy chủ dự kiến ​​sẽ trả về hồ sơ của người dùng được liên kết với mã thông báo đính kèm). Cảnh giác với CSRF khi sử dụng lưu trữ cookie.
sp00m

21

Cách đơn giản nhất để xác định hành vi tùy chỉnh cho các tuyến riêng lẻ sẽ khá dễ dàng:

1) routes.js: tạo một thuộc tính mới (như requireAuth) cho bất kỳ tuyến đường mong muốn nào

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) Trong bộ điều khiển cấp cao nhất không bị ràng buộc với một yếu tố bên trong ng-view(để tránh xung đột với góc $routeProvider), hãy kiểm tra xem tài sản đó newUrlcó thuộc requireAuthtính không và hành động tương ứng

 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");
         }
     });
 });

1
Chúng tôi có thể chỉ định thuộc tính 'notifyAuth: true' cho tất cả các tuyến đường ở một nơi không?. Bởi vì trong kịch bản của tôi, họ không phải là một trang đăng nhập nhưng nó được xác thực từ cuộc gọi nghỉ ngơi của bên thứ ba. Vì vậy, tôi muốn chỉ định ở một nơi, và nó cũng nên áp dụng cho các tuyến đường được thêm vào trong tương lai.
Raghuveer

1
Không phải là tôi biết. Có lẽ bạn có thể kiểm tra mọi tuyến đường mà KHÔNG có thuộc tính đặc biệt được xác định routes.js.
DotBot

1
Ví dụ tuyệt vời và đơn giản. Nó rất hữu ích cho nhu cầu của tôi.
lỗi505

6

Tôi đã viết một bài đăng vài tháng trước về cách thiết lập chức năng đăng ký và đăng nhập người dùng với Angular, bạn có thể kiểm tra nó tại http://jasonwatmore.com/post/2015/03/10/AngularJS-User-Registration-and -Login-example.aspx

Tôi kiểm tra xem người dùng đã đăng nhập vào $locationChangeStartsự kiện chưa, đây là app.js chính của tôi hiển thị điều này:

(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');
            }
        });
    }
 
})();

Đẹp viết lên. Tôi đã sử dụng nó để tham khảo. Cảm ơn bạn @Jason.
Venkat Kotra

2

Tôi cảm thấy như cách này là dễ nhất, nhưng có lẽ đó chỉ là sở thích cá nhân.

Khi bạn chỉ định tuyến đăng nhập của mình (và bất kỳ tuyến ẩn danh nào khác; ví dụ: / register, / logout, / refreshToken, v.v.), hãy thêm:

allowAnonymous: true

Vì vậy, một cái gì đó như thế này:

$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
}

Bạn không bao giờ cần chỉ định "allowAnonymous: false", nếu không có mặt, nó được giả định là sai, trong séc. Trong một ứng dụng mà hầu hết các URL được xác thực, điều này ít hoạt động hơn. Và an toàn hơn; nếu bạn quên thêm nó vào một URL mới, điều tồi tệ nhất có thể xảy ra là một URL ẩn danh được bảo vệ. Nếu bạn làm theo cách khác, chỉ định "Yêu cầu xác thực: đúng" và bạn quên thêm nó vào một URL, bạn đang rò rỉ một trang nhạy cảm ra công chúng.

Sau đó chạy nó bất cứ nơi nào bạn cảm thấy phù hợp nhất với thiết kế mã của bạn.

//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");
        }
    });
});

1

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');
                }

            });
        }
    });
});

loginService.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;
            */
        }
    }

});

sessionService.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
    };

}]);

1

Bạn có thể sử dụng resolve:

angular.module('app',[])
.config(function($routeProvider)
{
    $routeProvider
    .when('/', {
        templateUrl  : 'app/views/login.html',
        controller   : 'YourController',
        controllerAs : 'Your',
        resolve: {
            factory : checkLoginRedirect
        }
    })
}

Và, chức năng của giải quyết:

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 cũng có một phương pháp giúp bạn cài đặt một người quan sát, tôi khuyên bạn nên cài đặt nó bên trong .run:

.run(function(){

    firebase.auth().onAuthStateChanged(function(user) {
        if (user) {
            console.log('User is signed in.');
        } else {
            console.log('No user is signed in.');
        }
    });
  }

0

Chẳng hạn, một ứng dụng có hai người dùng gọi là ap và auc. Tôi đang chuyển một thuộc tính bổ sung cho mỗi tuyến và xử lý định tuyến dựa trên dữ liệu tôi nhận được trong $ routeChangeStart.

Thử cái này:

angular.module("app").config(['$routeProvider',
function ($routeProvider) {

    $routeProvider.
            when('/ap', {
                templateUrl: 'template1.html',
                controller: 'template1',
                isAp: 'ap',
            }).
            when('/auc', {
                templateUrl: 'template2.html',
                controller: 'template2',
                isAp: 'common',
            }).
            when('/ic', {
                templateUrl: 'template3.html',
                controller: 'template3',
                isAp: 'auc',
            }).
            when('/mup', {
                templateUrl: 'template4.html',
                controller: 'template4',
                isAp: 'ap',
            }).

            when('/mnu', {
                templateUrl: 'template5.html',
                controller: 'template5',
                isAp: 'common',
            }).                               
            otherwise({
                redirectTo: '/ap',
            });
   }]);

app.js:

.run(['$rootScope', '$location', function ($rootScope, $location) {                
    $rootScope.$on("$routeChangeStart", function (event, next, current) {
        if (next.$$route.isAp != 'common') {
            if ($rootScope.userTypeGlobal == 1) {
                if (next.$$route.isAp != 'ap') {
                    $location.path("/ap");
                }
            }
            else {
                if (next.$$route.isAp != 'auc') {
                    $location.path("/auc");
                }                        
            }
        }

    });
}]);

0

Tất cả đã đề xuất giải pháp lớn tại sao bạn lo lắng về phiên ở phía khách hàng. Ý tôi là khi trạng thái / url thay đổi Tôi cho rằng bạn đang thực hiện một cuộc gọi ajax để tải dữ liệu cho tempelate.

Note :- To Save user's data you may use `resolve` feature of `ui-router`.
 Check cookie if it exist load template , if even cookies doesn't exist than 
there is no chance of logged in , simply redirect to login template/page.

Bây giờ dữ liệu ajax được máy chủ trả về bằng bất kỳ api nào. Bây giờ điểm đã đi vào hoạt động, trả về các loại trả lại tiêu chuẩn bằng cách sử dụng máy chủ theo trạng thái đăng nhập của người dùng. Kiểm tra các mã trả lại và xử lý yêu cầu của bạn trong bộ điều khiển. Lưu ý: - Đối với bộ điều khiển không yêu cầu cuộc gọi ajax tự nhiên, bạn có thể gọi một yêu cầu trống đến máy chủ như thế này server.location/api/checkSession.phpvà đây là checkSession.php

<?php/ANY_LANGUAGE
session_start();//You may use your language specific function if required
if(isset($_SESSION["logged_in"])){
set_header("200 OK");//this is not right syntax , it is just to hint
}
else{
set_header("-1 NOT LOGGED_IN");//you may set any code but compare that same       
//code on client side to check if user is logged in or not.
}
//thanks.....

Về phía khách hàng bên trong bộ điều khiển hoặc thông qua bất kỳ dịch vụ nào như được hiển thị trong các câu trả lời khác

    $http.get(dataUrl)
    .success(function (data){
        $scope.templateData = data;
    })
    .error(function (error, status){
        $scope.data.error = { message: error, status: status};
        console.log($scope.data.error.status);
if(status == CODE_CONFIGURED_ON_SERVER_SIDE_FOR_NON_LOGGED_IN){
//redirect to login
  });

Lưu ý: - Tôi sẽ cập nhật thêm vào ngày mai hoặc trong tương lai


-1

Bạn nên kiểm tra xác thực người dùng trong hai trang web chính.

  • Khi người dùng thay đổi trạng thái, kiểm tra nó bằng '$routeChangeStart' gọi lại
  • Khi một yêu cầu $ http được gửi từ góc, sử dụng một bộ chặn.
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.