2013-11-28 3 views
6

При определении маршрутов приложения AngularJS, чтобы указать, какой уровень доступа должен иметь каждый маршрут, к каждому маршруту добавлено новое свойство access. Это основано на подходе к авторизации на стороне клиента, описанном here.Инициализировать блок конфигурации AngularJS с асинхронными данными

.config блока будет выглядеть следующим образом:

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

     var access = routingConfig.accessLevels; //Initialize with asynch data instead 

     $routeProvider. 
     when('/home', { 
      templateUrl: '/Templates/home.html', 
      controller: 'homeController', 
      access: access.user 
     }); 
     $routeProvider. 
     when('/private', { 
      templateUrl: '/Templates/private.html', 
      controller: 'adminController', 
      access: access.admin 
     }); 

     //...more route configurations 

    }]); 

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

Хотя есть ответы на Initialize AngularJS service with asynchronous data основе обнажая promise в службе & с помощью resolve в маршрутной конфигурации, он не будет работать в моем случае, когда я нужен асинхронный вызов будет разрешен до определения конфигурации маршрута, поскольку access свойство зависит от асинхронных данных.

Какие у меня варианты? Может ли подход promise/deferred по-прежнему использоваться?

Любое предложение было бы высоко оценено.

EDIT:

Чтобы описать то, что access делает немного, он заселяется отдельным модулем под названием routingConfig. В approach пользователь может принадлежать определенной роли, которая определяется как двоичное число. Например, например: 001, пользователь: 010, admin: 100 (и т. Д.).

Уровень доступа для любого маршрута снова будет двоичным числом, определяемым операцией ИЛИ всех пользовательских ролей, которым разрешен доступ к ней. Так, например, если доступ к уровню доступа user может выполняться пользовательскими ролями user (010) и admin (100), его битовая маска будет равна 110. Позже, чтобы проверить доступ к маршруту, мы можем выполнить операцию И по пользовательской роли и доступ -level, чтобы узнать, разрешено или нет. Подробности можно увидеть в приведенной выше ссылке.

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

Снова возвращаясь к проблеме в руке. Как может access, который используется как свойство в блоке config, инициализируется асинхронными данными, поступающими с сервера. Эти данные могут выглядеть следующим образом:

accessLevels : { 
    'public' : '111', 
    'user' : '110', 
    'admin': '100' 
} 
+0

Я предполагаю, что вы протестировали услугу для извлечения 'access', но по какой-то причине, когда вы используете его с $ routeProvider' access', ссылка потеряна и все, что вы используете 'access' позже, у вас нет значения обновления? Это выглядит странно в первом взгляде на меня. –

+0

Не могли бы вы указать, какая именно информация вам нужна для загрузки 'access' (или описания в целом некоторых сценариев)? (У меня есть пара идей, но все они далеки от элегантности). –

+0

Проблема в том, что '$ routeProvider' должен быть зарегистрирован _before_ приложение' running'. То, как мы справляемся с этим, - это определить маршруты одинаково, но установить правильный уровень доступа в функции 'module.run' и сделать ссылки недоступными через интерфейс. Если пользователь добирается до этих ссылок, он видит приятную ошибку 401 в приложении и просят войти в систему с более высокими привилегиями с помощью модального окна. Это обрабатывается через перехватчики '$ http'. –

ответ

2

Так что, если я понял, вы правильно приложение должно быть отвечать на запросы пока access не доступен. Так в чем же смысл азартно захватывать access?

Может быть, такой подход уместен [наверняка во многих подобных случаях должны быть]:

<script src="angular.js"></script> 
<script> 
angular.module('config').constant(
    <%= // JSON.stringify your config and access %> 
); 
</script> 
<script src="app.js"></script> 

Если вы действительно должны сделать это асинхронно, то с XHRHttpRequest или каким-либо другим способом захватить access и bootstrap приложения вручную.

0

Не уверен, что вы решили свою проблему в то же время, но я столкнулся с той же проблемой некоторое время назад. Мое решение состояло в том, чтобы использовать основной контроллер на теге html вместе с ng-app. Внутри контроллера я использовал полученные уровни доступа с моего сервера и определил свои маршруты там с помощью $route. Таким образом, данные доступны до того, как вы определите конфигурацию маршрутов. Разумеется, вы также можете назвать обещание then от фабрики Auth внутри контроллера и определить ваши маршруты там.

вид:

<html ng-app="app" ng-controller="MainController"> 
... 
</html> 

контроллер:

var MainController = ['$scope', '$http', '$route', 'Auth', function ($scope, $http, $route, Auth) { 
    var accessLevels = Auth.accessLevels; 

    $route.routes['/index'] = {templateUrl: "pages/index", controller: IndexController, access: accessLevels.guest}; 
    .... 
    $route.routes['null'] = {redirectTo: '/index', controller: IndexController}; 

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

  • Нет связанных вопросов^_^