AngularJS - Logowanie i uwierzytelnianie w każdej trasie i kontrolerze


131

Mam aplikację AngularJS stworzoną przy użyciu narzędzi yeoman, grunt i bower.

Mam stronę logowania, na której znajduje się kontroler sprawdzający uwierzytelnianie. Jeśli poświadczenia są poprawne, przekierowuję na stronę główną.

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

Na stronie głównej mam

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

W oknie loginControllersprawdzam dane logowania i jeśli się powiedzie, ustawiam obiekt użytkownika w fabryce usług. Nie wiem, czy to prawda, czy nie.

Potrzebuję tego, gdy użytkownik jest zalogowany, ustawia pewną wartość w obiekcie użytkownika, aby wszystkie inne strony mogły uzyskać tę wartość.

Za każdym razem, gdy dojdzie do zmiany trasy, kontroler powinien sprawdzić, czy użytkownik jest zalogowany. Jeśli nie, powinien przekierować do strony logowania. Ponadto, jeśli użytkownik jest już zalogowany i wraca na stronę, powinien przejść do strony głównej. Kontroler powinien również sprawdzić poświadczenia na wszystkich trasach.

Słyszałem o ng-cookies, ale nie wiem, jak ich używać.

Wiele z przykładów, które widziałem, nie było zbyt jasnych i wykorzystywały jakieś role dostępu lub coś w tym rodzaju. Nie chcę tego. Chcę tylko filtr logowania. Czy ktoś może mi dać jakieś pomysły?

Odpowiedzi:


182

Moje rozwiązanie składa się z 3 części: stan użytkownika jest przechowywany w usłudze, w metodzie uruchamiania, którą obserwujesz, gdy zmienia się trasa i sprawdzasz, czy użytkownik ma dostęp do żądanej strony, w głównym kontrolerze oglądasz, jeśli stan użytkownika zmienia się.

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

Powinieneś stworzyć usługę (nadam jej nazwę Auth), która będzie obsługiwać obiekt użytkownika i mieć metodę sprawdzania, czy użytkownik jest zalogowany, czy nie.

usługa :

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

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

Z twojego miejsca app.runpowinieneś wysłuchać $routeChangeStartwydarzenia. Gdy trasa ulegnie zmianie, sprawdzi czy użytkownik jest zalogowany ( isLoggedInmetoda powinna sobie z tym poradzić). Nie załaduje żądanej trasy, jeśli użytkownik nie jest zalogowany, i przekieruje użytkownika na właściwą stronę (w Twoim przypadku logowanie).

loginControllerPowinny być wykorzystywane na stronie logowania do obsługi logowania. Powinien po prostu współdziałać z Authusługą i ustawić użytkownika jako zalogowanego lub nie.

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

Z głównego kontrolera możesz nasłuchiwać, czy stan użytkownika zmienia się i reagować przekierowaniem.

.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
LoginController pozwoli użytkownikowi zalogować się ze strony logowania. Obsłuży formularz logowania. Formularz musi wywołać metodę przesyłania, która jest częścią twojego loginController. Ta metoda zaktualizuje (jeśli formularz jest poprawny i użytkownik musi być zalogowany) stan użytkownika KORZYSTAJĄC z opisanej przeze mnie usługi Auth.
gab

2
Działał jak urok! Zamiast dostarczonej usługi użyłem Auth0 z AngularJS .
Nikos Baxevanis

34
Co się stanie, jeśli użytkownik naciśnie klawisz F5 i odświeży się? Wtedy Twoje w pamięci Auth zniknęło.
Gaui

4
Na wypadek, gdyby inni mieli problemy z uruchomieniem tego przykładu: w routeChangeStartwywołaniu zwrotnym należy sprawdzić, czy lokalizacja to faktycznie „/ login” i pozwolić na to:if ( $location.path() === "/login" ) return;
user2084865

1
to mnie w nieskończonej pętli.
Nipun Tyagi

112

Oto inne możliwe rozwiązanie, używając resolveatrybutu $stateProviderlub $routeProvider. Przykład z $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 rozpatruje lub odrzuca obietnicę w zależności od aktualnych uprawnień użytkownika:

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

}])

UserProfilekopie obecne właściwości użytkownika, oraz wykonuje $hasRole, $hasAnyRole, $isAnonymousi $isAuthenticatedsposoby logiczny (plus $refreshmetoda wyjaśnione później):

.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 jest odpowiedzialny za żądanie serwera, aby poznać profil użytkownika (na przykład powiązany z tokenem dostępu dołączonym do żądania):

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

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

}])

Oczekuje się, że serwer zwróci taki obiekt JSON podczas żądania 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
}

Wreszcie, gdy Accessodrzuca obietnicę, jeśli ją używasz ui.router, $stateChangeErrorzdarzenie zostanie uruchomione :

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

    }
  });

}])

Jeśli używasz ngRoute, $routeChangeErrorzdarzenie zostanie uruchomione :

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

    }
  });

}])

Dostęp do profilu użytkownika można również uzyskać w kontrolerach:

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

UserProfilenastępnie zawiera właściwości zwrócone przez serwer podczas żądania GET api/auth:

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

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

}])

UserProfilemusi być odświeżany, gdy użytkownik loguje się lub wylogowuje, aby Accessmógł obsługiwać trasy z nowym profilem użytkownika. Możesz przeładować całą stronę lub zadzwonić UserProfile.$refresh(). Przykład podczas logowania:

.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
Myślę, że jest to najprostsza i najbardziej rozszerzalna odpowiedź
Jotham

2
@LeblancMeneses Thanks :) Tylko dla wyjaśnienia: NIEAUTORYZOWANY oznacza „nie wiemy, kim jesteś, więc nie możemy powiedzieć, czy masz uprawnienia dostępu do tego zasobu, czy jeszcze nie, zaloguj się najpierw” , a ZABRONIONE oznacza „wiemy, kim jesteś, a Twój profil nie pozwala na dostęp do tego zasobu” .
sp00m

1
Niezłe rozwiązanie, potencjalne dopasowanie z uwierzytelnianiem Spring po stronie serwera
Jan Peter,

1
Najlepsze rozwiązanie w historii!
Renan Franca

1
@jsbisht Wszystko zależy od tego, gdzie przechowujesz tokeny dostępu (zobacz ostatni fragment). Jeśli przechowujesz go tylko w pamięci JS, to tak: F5 usunie informacje o autoryzacji. Ale jeśli przechowujesz go w trwałym magazynie (np. Cookie / localStorage / sessionStorage), to nie: F5 nie usunie informacji o uwierzytelnianiu (o ile dołączysz token do każdego żądania $ http lub przynajmniej do żądań wysyłanych do rest / users / profile, ponieważ oczekuje się, że serwer zwróci profil użytkownika połączonego z dołączonym tokenem). Uważaj jednak na CSRF podczas korzystania z przechowywania plików cookie.
sp00m

21

Najprostszy sposób zdefiniowania niestandardowego zachowania dla poszczególnych tras byłby dość łatwy:

1) routes.js: utwórz nową właściwość (lubię requireAuth) dla dowolnej żądanej trasy

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) W kontrolerze najwyższego poziomu, który nie jest powiązany z elementem wewnątrz ng-view(aby uniknąć konfliktu z angular $routeProvider), sprawdź, czy właściwość newUrlma requireAuthwłaściwość i postępuj odpowiednio

 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
Czy możemy określić atrybut „requireAuth: true” dla wszystkich tras w jednym miejscu? Ponieważ w moim scenariuszu nie jest to strona logowania, ale jest uwierzytelniana przez wywołanie reszty strony trzeciej. Chciałem więc określić w jednym miejscu i powinno to dotyczyć również przyszłych dodawanych tras.
Raghuveer

1
Nie żebym o tym wiedział. Być może możesz sprawdzić każdą trasę, która NIE ma zdefiniowanej specjalnej właściwości routes.js.
DotBot

1
Świetny i prosty przykład, który był bardzo pomocny dla moich potrzeb.
błąd 505

7

Kilka miesięcy temu napisałem post o tym, jak skonfigurować rejestrację użytkownika i funkcjonalność logowania w Angular, możesz to sprawdzić na http://jasonwatmore.com/post/2015/03/10/AngularJS-User-Registration-and -Login-Example.aspx

Sprawdzam, czy użytkownik jest zalogowany w $locationChangeStartzdarzeniu, oto moja główna aplikacja.js pokazująca to:

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

Niezły opis. Użyłem go w celach informacyjnych. Dziękuję @Jason.
Venkat Kotra,

2

Wydaje mi się, że ten sposób jest najłatwiejszy, ale może to tylko osobiste preferencje.

Po określeniu trasy logowania (i wszelkich innych tras anonimowych; np. / Register, / logout, / refreshToken itp.), Dodaj:

allowAnonymous: true

Więc coś takiego:

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

Nigdy nie musisz określać „allowAnonymous: false”, jeśli nie jest obecne, przyjmuje się, że podczas sprawdzania jest fałsz. W aplikacji, w której większość adresów URL jest wymuszonych uwierzytelniania, jest to mniej pracy. I bezpieczniejsze; jeśli zapomnisz dodać go do nowego adresu URL, najgorsze, co może się zdarzyć, to ochrona anonimowego adresu URL. Jeśli zrobisz to w inny sposób, określając „requireAuthentication: true” i zapomnisz dodać go do adresu URL, ujawniasz publicznie wrażliwą stronę.

Następnie uruchom to tam, gdzie uważasz, że najlepiej pasuje do Twojego projektu kodu.

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

            });
        }
    });
});

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

}]);

1

Możesz użyć resolve:

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

I funkcja rozwiązania:

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 ma również metodę, która pomaga zainstalować obserwatora, radzę zainstalować go w .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

Na przykład aplikacja ma dwóch użytkowników o nazwach ap i auc. Przekazuję dodatkową właściwość do każdej trasy i obsługuję routing na podstawie danych, które otrzymuję w $ routeChangeStart.

Spróbuj tego:

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

Wszyscy zasugerowali duże rozwiązanie, dlaczego martwisz się sesją po stronie klienta. Mam na myśli, kiedy zmienia się stan / adres URL, przypuszczam, że wykonujesz wywołanie ajax, aby załadować dane dla 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.

Teraz dane AJAX są zwracane przez serwer przy użyciu dowolnego interfejsu API. Teraz chodziło o zwrócenie standardowych typów zwrotów przy użyciu serwera zgodnie ze statusem zalogowanego użytkownika. Sprawdź te kody zwrotne i przeprowadź swoje żądanie w kontrolerze. Uwaga: - W przypadku kontrolera, który nie wymaga natywnie wywołania ajax, możesz wywołać puste żądanie do serwera w ten sposób, server.location/api/checkSession.phpa to jest 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.....

Po stronie klienta w kontrolerze lub za pośrednictwem dowolnej usługi, jak pokazano w innych odpowiedziach

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

Uwaga: - jutro lub w przyszłości zaktualizuję więcej


-1

Powinieneś sprawdzić uwierzytelnianie użytkowników w dwóch głównych witrynach.

  • Gdy użytkownicy zmieniają stan, sprawdzają to za pomocą '$routeChangeStart'wywołania zwrotnego
  • Gdy żądanie $ http jest wysyłane z angulara przy użyciu przechwytywacza.
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.