2013-10-28 6 views
9

Queste domande si riferiscono al progetto angular-app e al modo in cui esso autentica gli utenti.Angular-app, autenticazione e ordine dei risolutori nel router (ui-)

L'implementazione originale protegge l'accesso ad alcuni URL utilizzando la clausola di risoluzione sul router. Sembra:

$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 
} 

});

La vista non viene visualizzata finché un utente non viene autenticato e i progetti vengono recuperati (per evitare lo sfarfallio). Se un utente non è autenticato, compare il popup di accesso e, dopo che l'utente lo invia, la promessa viene risolta e viene visualizzata una pagina richiesta. Funziona bene se auth non è richiesta sulla chiamata Projects.all().

Ecco il log delle chiamate al server:

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" 

La chiamata a angular_app/collezioni/progetti è valida anche per l'utente non autenticato.

Nel mio caso ho il seguente codice:

$stateProvider 
    .state('root.tickets', { 
     url: '/tickets', 
     views: { 
      '[email protected]': { 
       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 
       } 
      } 
     } 

La differenza è (tranne io uso ui-router e Restangular) che la chiamata API deve essere autenticata. Il registro del server è simile al seguente:

[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 

Nota codice di stato 403 qui. L'effetto è che l'utente vede il popup di accesso, autentica ma poi vede la pagina vuota. Suppongo che ciò sia dovuto al fatto che i dati recuperano l'errore di promessa.

La mia domanda è: è in qualche modo possibile forzare l'ordine delle promesse? Vorrei innanzitutto verificare se l'utente è autenticato, quindi inviare una chiamata al back-end, ecc. O c'è qualche altra soluzione che posso usare qui? Sto imparando Angular quindi anche se c'è una soluzione semplice non è ovvio per me.

+0

'securityAuthorizationProvider.requireAuthenticatedUser', questa è una proprietà o funzione? – Chandermani

+0

È una funzione. Vedi: https://github.com/angular-app/angular-app/blob/master/client/src/common/security/authorization.js#L21 – eXt

risposta

15

Mi piace usare lo schema del resolver ma trovo molto difficile eseguire questo tipo di operazioni nel router ui angolare.

una soluzione è alla dipendenza iniettare il risultato del resolver authenticatedUser nel risolutore chiamata API che si desidera proteggere come:

$stateProvider 
    .state('root.tickets', { 
     url: '/tickets', 
     views: { 
      '[email protected]': { 
       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(); 
        } 
       } 
      } 
     } 

In questo modo i risolutori verrà eseguito in una catena (authenticatedUser -> ticketsy) piuttosto che asincrono tutto in una volta.

Spero che questo abbia aiutato .. vorrei che ci fosse un modo migliore di farlo .. questo è il motivo per cui la ricerca attraverso lo stack overflow.

+0

Questo ha funzionato perfettamente per me in una situazione simile a @eXt. – JDWardle

+0

non funziona con angolare 1.2.19. Continuo a ricevere un "provider sconosciuto authenticatedUserProvider". Mi sto perdendo qualcosa ? –

+0

@ Cétia È perché la risposta inviata utilizza UI Router e non il router angolare. Un po 'in ritardo ma meglio tardi che mai. :) –

0

Hai provato qualcosa di simile.

return securityAuthorizationProvider.requireAuthenticatedUser().then(function() { 
    return Restangular.all('tickets').getList(); 
}); 

Fondamentalmente requireAuthenticatedUser restituisce una promessa così è possibile concatenare con la chiamata a chiamata Restangular.

+0

Ho provato questo, ma dopo di ciò né la pagina è resa né alcuna l'errore è stato generato Strano. – eXt

Problemi correlati