This questions refers to the angular-app project and the way it authenticates users.
The original implementation guards access to some urls by using resolve clause on the router. This looks like:
$routeProvider.when('/projects', {
templateUrl:'projects/projects-list.tpl.html',
controller:'ProjectsViewCtrl',
resolve:{
projects:['Projects', function (Projects) {
//TODO: fetch only for the current user
return Projects.all();
}],
authenticatedUser: securityAuthorizationProvider.requireAuthenticatedUser
}
});
The view is not rendered until a user is authenticated and projects are fetched (to prevent ui flickering). If a user is not authenticated then login popup pops up and after user submits it then the promise is resolved and a requested page is displayed. This works nice if auth is not required on Projects.all() call.
Here's the log of server calls:
127.0.0.1 - - [Mon, 28 Oct 2013 11:15:47 GMT] "GET /projects HTTP/1.1" 200 739 "-" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
Unauthenticated
127.0.0.1 - - [Mon, 28 Oct 2013 11:15:47 GMT] "GET /current-user HTTP/1.1" 200 24 "http://localhost:3000/projects" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
Unauthenticated
Unauthenticated
127.0.0.1 - - [Mon, 28 Oct 2013 11:15:47 GMT] "GET /current-user HTTP/1.1" 200 24 "http://localhost:3000/projects" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
127.0.0.1 - - [Mon, 28 Oct 2013 11:15:47 GMT] "GET /databases/angular_app/collections/projects?q=%7B%7D HTTP/1.1" 200 10 "http://localhost:3000/projects" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
Unauthenticated
127.0.0.1 - - [Mon, 28 Oct 2013 11:15:59 GMT] "POST /login HTTP/1.1" 200 161 "http://localhost:3000/projects" "Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0"
The call to angular_app/collections/projects is valid even for unauthenticated user.
In my case I have the following code:
$stateProvider
.state('root.tickets', {
url: '/tickets',
views: {
'container@': {
templateUrl: 'tickets/tickets-list.tpl.html',
controller:'TicketsViewCtrl',
resolve:{
ticketsy: ['Restangular', function (Restangular) {
//Call to tickets must be authenticated
return Restangular.all('tickets').getList();
}],
authenticatedUser: securityAuthorizationProvider.requireAuthenticatedUser
}
}
}
The difference is (except I use ui-router and Restangular) that the api call has to be authenticated. Server log looks like:
[28/Oct/2013 05:50:15] "GET /api/tickets/ HTTP/1.1" 403 59
[28/Oct/2013 05:50:15] "GET / HTTP/1.1" 200 963
[28/Oct/2013 05:50:16] "GET /api/current-user/ HTTP/1.1" 200 14
[28/Oct/2013 05:50:16] "GET /api/tickets HTTP/1.1" 301 0
[28/Oct/2013 05:50:16] "GET /api/tickets/ HTTP/1.1" 403 59
[28/Oct/2013 05:50:22] "POST /api/login/ HTTP/1.1" 200 120
Note 403 status code here. The effect is that user sees login popup, authenticates but then sees empty page. I suppose this is because of data fetching promise failure.
My question is - is it somehow possible to force order of promises? I'd like to first check if user is authenticated then issue a call to the backend etc. Or is there any other solution I can use here? I'm learning Angular so even if there's a simple solution it is not obvious to me.
I love using the resolver pattern but find it very difficult to do these types of things in angular ui router.
one solution is to dependency inject the result of the authenticatedUser resolver into the api call resolver you want protected like:
$stateProvider
.state('root.tickets', {
url: '/tickets',
views: {
'container@': {
templateUrl: 'tickets/tickets-list.tpl.html',
controller:'TicketsViewCtrl',
resolve:{
authenticatedUser: securityAuthorizationProvider.requireAuthenticatedUser,
ticketsy: function (Restangular, authenticatedUser) {
//Call to tickets must be authenticated
return Restangular.all('tickets').getList();
}
}
}
}
This way the resolvers will run in a chain (authenticatedUser -> ticketsy) rather than async all at once.
I hope this helped.. wish there was a better way of doing it.. thats why im search through stack overflow.
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