2015-02-28 2 views
1

Я пишу cms front-end в Angular JS, и я не знаю, как разрешить пользователю разрешить пользователю просматривать конкретный контент при первой загрузке приложения. У меня есть рабочее решение, когда пользователь уже входит в систему и просто перемещается со страницы на страницу. Я делаю это так:Угловая авторизация JS - проверьте роль пользователя перед загрузкой страницы

angular.module("myApp") 
 
.run ($rootScope, AUTH_EVENTS, AuthServ) -> 
 
    $rootScope.$on '$stateChangeStart', (event, next) -> 
 
     if next.data 
 
     authorizedRoles = next.data.authorizedRoles 
 
     unless AuthServ.isAuthorized(authorizedRoles) 
 
      event.preventDefault() 
 
      if AuthServ.isAuthenticated() 
 
      $rootScope.$broadcast(AUTH_EVENTS.notAuthorized) 
 
      else 
 
      $rootScope.$broadcast(AUTH_EVENTS.notAuthenticated)

Когда пользователь изменить маршрут, то AuthServ.isAuthorized (authorizedRoles) обжигают.

Когда пользователь входит в систему, я получаю токены и пользовательские данные с сервера. Токен хранится в локальном хранилище, а данные пользователя хранятся в памяти (в области верхнего уровня контроллера). В пользовательских данных у меня есть информация о его роли, поэтому я могу проверить, разрешено ли ему видеть конкретный контент.

Теперь предположим, что пользователь вошел в систему, и он перезагрузит страницу. У меня все еще есть токен, поскольку он находится в localStorage, но я теряю пользовательские данные (поэтому я не знаю, какова его роль). Я не хочу показывать какой-либо контент пользователю, прежде чем я получу его данные снова с сервера. Итак, мой вопрос - как решить это? Где и когда я должен сделать запрос на сервер для пользовательских данных?

Я думал, что решение может быть связано с ручной загрузкой приложения. Я пытался сделать что-то вроде этого:

app = angular.module('myApp', []) 
 

 
fetchData = -> 
 
\t injector = angular.injector(['ng']) 
 
\t $http = injector.get('$http') 
 
\t API_URI = injector.get('API_URI') 
 
\t $localStorage = injector.get('$localStorage') 
 

 
\t $http.get("#{API_URI}/users/me?token=#{$localStorage.token}") 
 
\t \t .success (data) -> 
 
\t \t \t app.constant('USER_DATA', data) 
 

 
bootstrapApplication = -> 
 
\t angular.element(document).ready -> 
 
\t \t angular.bootstrap(document, ['myApp']) 
 

 
fetchData().then(bootstrapApplication)

Проблема с этим кодом является то, что у меня нет доступа к сервису $ LocalStorage и постоянной API_URI. Мне нужно, чтобы они получили токен и динамически изменяли URL-адрес (разработка, производство).

Итак, что является лучшим решением? Возможно, хранение роли пользователя в локальном хранилище?

Любая помощь была бы оценена, спасибо.

ответ

0

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

+0

У меня нет проблем с сохранением пользовательских данных при навигации между страницами. Как вы упомянули, пользовательские данные фактически хранятся в отдельной службе, а в контроллере я просто назначаю их в область. Неважно, сохраняете ли вы свои данные в сервисе -> у вас все еще есть их только в памяти. Поэтому на странице обновления вы теряете их. Итак, это вопрос: как управлять данными пользователя, чтобы сохранить их, даже если пользователь обновляет страницу? – wawka

+0

Это был момент, если вы продолжаете работать, он не затеряется при обновлении. – Safi

+0

Я так не думаю. Сервис хранится только в памяти. Поэтому, когда вы обновляете страницу, услугу нужно снова воссоздать. Любые данные, которые не хранятся в постоянной памяти (например, локальное хранилище, будут потеряны). Другим решением может быть снова запросить сервер о пользовательских данных. – wawka

2

Вы можете использовать решение Angular на своих маршрутах конфигурации. Вот пример, когда я разрешаю «пользователь» для определенного маршрута. Он должен решить, прежде чем угловой будет загружать этот маршрут.

app.config([ '$routeProvider', '$locationProvider', 
    function($routeProvider, $locationProvider) { 

     $routeProvider 
      .when('/somePath', { 
       templateUrl: "someView.html", 
       controller: "someController", 
       resolve: { 
        user: function(authService){ 
         return authService.getUser(); 
        } 
       } 
      } 
     ); 

    } 
]); 

Вот сервис (завод в этом случае), чтобы согласиться с ним. Я проверяю, чтобы увидеть, если auth.user существует первый, так что не будет запрос на каждом изменении маршрута:

app.factory('authService', [ '$http', '$q', 
    function($http, $q) { 

     var pub = {}; 

     pub.user = null; 

     pub.getUser = function() { 

      var deferred = $q.defer(); 

      if(pub.user) { 
       deferred.resolve(pub.user); 
      } 

      else{ 
       $http.get('/someAuthUrl').then(function(user) { 
        pub.user = user; 
        deferred.resolve(user); 
       }); 
      } 

      return deferred.promise; 

     }; 

     return pub; 

    } 
]); 

И, наконец, контроллер, который не будет загружаться, пока функция аутентификации не разрешена с необходимым пользователем данные. Теперь вы можете получить доступ к объекту пользователя через инъекцию.

app.controller('someController', [ '$scope', 'user', 
    function($scope, user) { 

     //Controller runs here only when user is resolved. 
     // Anything resolved will be passed in as your last dependency. 
     $scope.user = user; 

    } 
]); 

В этом случае вы могли бы впрыскивается службу в контроллер вместо этого и использовать authService.user, как мы знаем, это доступно.

app.controller('someController', [ '$scope', 'authService', 
    function($scope, authService) { 

     $scope.user = authService.user; 

    } 
]); 
+0

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

+0

Вы делаете несколько хороших пунктов на негативах использования решения. Я еще раз подумаю и посмотрю, смогу ли я придумать лучшее решение. – jeff

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