2016-11-15 2 views
2

В настоящее время я использую $rootScope для хранения информации о пользователе и независимо от того, вошел ли пользователь в систему. Я пробовал использовать $window.localStorage, но безуспешно. Моя цель состоит в том, чтобы элементы в моем навигаторе появлялись через ng-show после входа пользователя в систему, отображали свое имя пользователя на панели навигации, в виде отдельного профиля пользователя, просмотра всех пользователей и т. Д. Мне нужен постоянный логин. У меня есть navbar, работающий с $rootscope, но всякий раз, когда я пытаюсь перейти на $window.localStorage, он терпит неудачу. Вот код, с помощью $rootScope:Использование локального хранилища для хранения данных AngularJS

mainModule

angular.module('mainModule', [ 
     'ui.router', 
     ... 
    ]) 
    .config(configFunction) 
    .run(['$rootScope', '$state', 'Auth', function($rootScope, $state, Auth) { 
     $rootScope.$on('$stateChangeStart', function(event, next) { 
      if (next.requireAuth && !Auth.getAuthStatus()) { 
       console.log('DENY'); 
       event.preventDefault(); 
       $state.go('login'); 
      } else if (Auth.getAuthStatus() || !Auth.getAuthStatus()) { 
       console.log('ALLOW'); 
      } 
     }); 
    }]); 

Auth завод

angular.module('authModule').factory('Auth', ['$http', '$state', function authFactory($http, $state) { 
     var factory = {}; 

     var loggedIn = false; 
     var userData = {}; 

     factory.getAuthStatus = function() { 
      $http.get('/api/v1/auth') 
       .success(function(data) { 
        if (data.status == true) { 
         loggedIn = true; 
        } else { 
         loggedIn = false; 
        } 
       }) 
       .error(function(error) { 
        console.log(error); 
        loggedIn = false; 
       }); 
      return loggedIn; 
     } 

     return factory; 
    }]); 

Войти Контроллер

function SigninController($scope, $rootScope, $http, $state) { 
    $scope.userData = {}; 

    $scope.loginUser = function() { 
     $http.post('api/v1/login', $scope.userData) 
      .success((data) => { 
       $scope.userData = data.data; 
       $rootScope.loggedIn = true; 
       $rootScope.userData = data; 
       $state.go('home'); 
      }) 
      .error((error) => { 
       console.log('Error: ' + error); 
      }); 
    }; 
} 

Nav контроллер

function NavbarController($scope, Auth) { 
    $scope.loggedIn = Auth.getAuthStatus(); 
} 

EDIT EDIT EDIT

Вот как я использую локальное хранилище. Это единственное, что изменилось.

Войти Контроллер

function SigninController($scope, $window, $http, $state) { 
    $scope.userData = {}; 

    $scope.loginUser = function() { 
     $http.post('api/v1/login', $scope.userData) 
      .success((data) => { 
       $scope.userData = data.data; 
       $window.localStorage.setItem('userData', angular.toJson(data)); 
       $window.localStorage.setItem('loggedIn', true); 
       $state.go('home'); 
      }) 
      .error((error) => { 
       console.log('Error: ' + error); 
      }); 
    }; 
} 

Auth завод

angular 
    .module('authModule') 
    .factory('Auth', ['$http', '$window', '$state', function authFactory($http, $window, $state) { 
     var factory = {}; 

     factory.getAuthStatus = function() { 
      $http.get('/api/v1/auth') 
       .success(function(data) { 
        if (data.status == true) { 
         $window.localStorage.setItem('loggedIn', true); 
        } else { 
         $window.localStorage.setItem('loggedIn', false); 
        } 
       }) 
       .error(function(error) { 
        console.log(error); 
        $window.localStorage.setItem('loggedIn', false); 
       }); 
      return $window.localStorage.getItem('loggedIn'); 
     } 

     return factory; 
    }]); 
+2

Не могли бы вы показать свою попытку, которая не работает? Кроме того, используйте localStorage, а не $ window.localStorage. Кроме того, localStorage хранит только строки, поэтому вы захотите использовать JSON.stringify() и JSON.parse() для хранения/извлечения ваших объектов в localStorage – holtc

+0

@holtc Да, дайте мне несколько минут! Спасибо! – 2b2a

+0

@holtc It up up! Не могли бы вы объяснить, почему бы не использовать $ window.localStorage? Мой пример использует это, потому что это то, что я использовал раньше. – 2b2a

ответ

2

Я вижу потенциальную проблему с использованием localStorage.getItem('loggedIn').

Поскольку LocalStorage только хранит строки, что вы получите обратно на самом деле является строковой версией булева, что вы положили в. Если строке 'false' получает возвращенную, ваша проверка !Auth.getAuthStatus() в основном модуле, например, всегда будут вычисляться булева false, потому что любая непустая строка в JavaScript является «правдой».

т.е. !'false' === false (такой же, как !true === false)

Вы можете получить за это с помощью JSON.parse на значении LocalStorage. например JSON.parse(localStorage.getItem('loggedIn')) будет разбирать строку 'false' с булевым false.

+0

Хорошая точка в правдивой проблеме. +1 – MBielski

1

Просто замените $window.localStorage на window.localStorage, и все должно быть в порядке.

Например:

function SigninController($scope, $window, $http, $state) { 
    $scope.userData = {}; 

    $scope.loginUser = function() { 
     $http.post('api/v1/login', $scope.userData) 
      .success((data) => { 
       $scope.userData = data.data; 
       window.localStorage.setItem('userData', angular.toJson(data)); 
       window.localStorage.setItem('loggedIn', true); 
       $state.go('home'); 
      }) 
      .error((error) => { 
       console.log('Error: ' + error); 
      }); 
    }; 
} 

Это, как говорится, хранение аутентификации статуса в LocalStorage (или sessionStorage) не хороший путь, чтобы идти вниз. Обе пары «ключ/значение» могут быть прочитаны в панели разработчика, а затем изменены (ака поддельные) через консоль.Лучшее решение - вернуть уникальное значение (GUID) после успешного входа в систему и сохранить его в файле cookie (срок действия истекает через короткий промежуток времени, например 20 минут), который можно прочитать на сервере и проверить там. Вы можете и должны использовать для этого $cookie. Ваше состояние входа в систему должно контролироваться на стороне сервера, а не на стороне клиента. Клиент должен всегда доказывать, что он аутентифицирован.

Чтобы сохранить регистрацию, создайте службу, которая обрабатывает посетителя, и позвольте этой службе обрабатывать логин/выход из системы и предоставить доказательство того, что вы вошли в систему. Это доказательство того, что вы вошли в систему, должно всегда быть частным значением, которое хранится внутри службы и не доступны за ее пределами.

(function() { 
    'use strict'; 

    var visitorModelService = ['$http', function ($http) { 
      var loggedIn = false, 
       visitorModel = { 
        login:function(){ 
         //do login stuff with $http here 
         //set loggedIn to true upon success 
        }, 
        loggedIn:function(){ 
         return loggedIn; 
        }, 
        logout:function(){ 
         //do logout stuff with $http here 
         //no matter what, set loggedIn to false 
        } 
      }; 
      return visitorModel; 
     }]; 

    var module = angular.module('models.VisitorModel', []); 
    module.factory('VisitorModel', visitorModelService); 
}()); 

Делая это, вы можете просто проверить visitor.loggedIn в вашем ng-show и есть все централизованные. Такие, как:

<a ng-click='visitor.logout' ng-show='visitor.loggedIn'>Log Out</a> 

еще лучше, положить элементы, которые видны только пользователям, прошедшим проверку в div теге и скрыть/показать их ан-масс.

Смежные вопросы