While defining the routes of an AngularJS application, in order to indicate what access level each route should have, a new property called access
has been added to each route. This is based on a Client-Side authorization approach described here.
The .config
block would look like the following:
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
}]);
Leaving the core logic of the approach aside, I just want to know in general how can we initialize the access
variable with some asynchronous data so that it is available while defining the access
property for each route? This is needed because only the server has knowledge of the list of access levels.
Although there are answers to Initialize AngularJS service with asynchronous data based on exposing a promise
in the service & using resolve
in route config, it won't work in my case as I need the asynchronous call to be resolved before defining the route configuration because the access
property depends on the asynchronous data.
What options do I have? Can the promise/deferred approach still be used somehow?
Any suggestion would be much appreciated.
EDIT :
To describe what access
is doing a bit, it is being populated by a separate module called routingConfig
. In the approach, a user can belong to a certain role which is defined as a binary number. For e.g public : 001, user : 010, admin : 100 (and so forth).
The access level for any route will again be a binary number defined by the OR operation of all user-roles that are allowed to access it. So for e.g. if the user
access-level can be accessed by user-roles user
(010) and admin
(100), its bitmask would be 110. Later to check access on a route, we can do a AND operation on the user-role and access-level to see if it is authorized or not. Details can be seen in the above link.
Note that data at the server end is still secure by more complex algorithms, so even if the above logic is manipulated with at the client-side, such a user would only be able to see the markup of any unauthorized page.
Again, coming back to the problem in hand. How can access
which is being used as a property in the config
block be initialized with asynchronous data that comes from the server. This data may look like the following:
accessLevels : {
'public' : '111',
'user' : '110',
'admin': '100'
}
So if I understood you correctly the application should be unresponsive until the access
is available. So what is the point to grab access
asynchronously, anyway?
Maybe such approach is appropriate [for sure in many similar cases it should be]:
<script src="angular.js"></script>
<script>
angular.module('config').constant(
<%= // JSON.stringify your config and access %>
);
</script>
<script src="app.js"></script>
If you really have to done it asynchronously then with XHRHttpRequest
or some other way grab the access
and bootstrap
your application manually.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With