2014-06-08 4 views
10

Sto utilizzando la libreria cloudscape angularjs-devise sul client. Quando provo ad accedere/registrare ottengo una risposta di 200 ok con l'oggetto utente semplice visibile nella console chrome js. L'aggiornamento della pagina sembra perdere queste informazioni anche se ho assunto che il servizio lo memorizzasse ad un certo punto poiché ha anche i metodi di logout e currentUser. https://github.com/cloudspace/angular_deviseCome posso memorizzare e impostare l'utente su questo servizio di autenticazione della libreria di angularjs devise? O è già stato fatto?

Le mie domande sono:

1) È questo il servizio effettivamente memorizzare l'utente e se sì, come (vale a dire con i biscotti o localStorage o in memoria)?

2) Se il servizio non memorizza l'utente come posso memorizzare queste informazioni in un cookie personalizzato/localstorage e, più importante, impostare l'utente nel servizio in modo che i metodi "autenticati" e "currentuser" possano essere utilizzati ?

parziali Istruzioni Biblioteca Leggimi

Basta registrarsi Devise come una dipendenza per il modulo. Quindi, il servizio Auth sarà disponibile per l'uso.

angular.module('myModule', ['Devise']). 
    config(function(AuthProvider) { 
     // Configure Auth service with AuthProvider 
    }). 
    controller('myCtrl', function(Auth) { 
     // Use your configured Auth service. 
    }); 

Auth.login (creds): utilizzare Auth.login() per l'autenticazione con il server. Tieni presente che le credenziali vengono inviate in testo normale; utilizzare una connessione SSL per proteggerli. creds è un oggetto che dovrebbe contenere tutte le credenziali necessarie per l'autenticazione con il server. Auth.login() restituirà una promessa che verrà risolta all'utente connesso. Vedere AuthProvider.parse() per analizzare l'utente in un oggetto utilizzabile.

angular.module('myModule', ['Devise']). 
    controller('myCtrl', function(Auth) { 
     var credentials = { 
      email: '[email protected]', 
      password: 'password1' 
     }; 

     Auth.login(credentials).then(function(user) { 
      console.log(user); // => {id: 1, ect: '...'} 
     }, function(error) { 
      // Authentication failed... 
     }); 
    }); 

mio codice parziale:

main.js

var myApp = angular.module('mail_app', ['ngRoute', 'ngResource', 'Devise']); 

myApp.config(function($routeProvider, $locationProvider, $httpProvider, AuthProvider) { 
    console.log("in router") 
    $locationProvider.html5Mode(true); 
    $httpProvider.defaults.headers.common['X-CSRF-Token'] = 
    $('meta[name=csrf-token]').attr('content'); 
    $httpProvider.defaults.headers.common['ClientType'] = 'browser'; 

    // Customise login 
    AuthProvider.loginMethod('POST'); 
    AuthProvider.loginPath('/api/v1/users/login.json'); 

    // Customise register 
    AuthProvider.registerMethod('POST'); 
    AuthProvider.registerPath('/api/v1/users.json'); 

}); 

SessionsController.js

myApp.controller('SessionsController', ['$scope', 'Auth', '$http', function($scope, Auth, $http) { 
console.log("in session controller") 
    console.log(Auth.isAuthenticated()); 

    $scope.loginUser = function() { 
     console.log("in login") 
     var credentials = { 
      email: $scope.email, 
      password: $scope.password 
     }; 

     Auth.login(credentials).then(function(user) { 
      $scope.authError = 'Success!'; 
      console.log(user); // => {id: 1, ect: '...'} 
      Auth.currentUser = user; 
     }, function(error) { 
      $scope.authError = 'Authentication failed...'; 
     });  
    }; 

    $scope.registerUser = function(){ 
     console.log("in register function") 
     var ncredentials = { 
      email: $scope.newEmail, 
      password: $scope.newPassword, 
      password_confirmation: $scope.newPasswordConfirmation 
     }; 

     Auth.register(ncredentials).then(function(registeredUser) { 
      console.log(registeredUser); // => {id: 1, ect: '...'}; 
     }, function(error) { 
      $scope.authError = 'Registration failed...'; 
     }); 
    }; 

    $scope.getCurrentUser = function(){ 
     Auth.currentUser().then(function(user) { 
      // User was logged in, or Devise returned 
      // previously authenticated session. 
      console.log(user); // => {id: 1, ect: '...'} 
      $scope.id = user.id; 
     }, function(error) { 
      // unauthenticated error 
     });  
    }; 

    $scope.isUserAuthenticated = function(){ 
     Auth.isAuthenticated();  
    }; 


}]); 
+0

La mia ipotesi migliore è che è necessario utilizzare il remember_me su devise in modo che crei un cookie permanente anziché uno di sessione. –

+1

Qualche idea su come farlo attraverso l'api? Di solito invio una richiesta POST con i dati dell'utente a "/users/sign_in.json". Quali informazioni posso aggiungere alla richiesta per remember_me? –

risposta

4

Prima di tutto è necessario capire come i cookie e sessioni di lavoro in Rails.

Da this articolo:

Rails utilizza un CookieStore per gestire le sessioni. Ciò significa che tutte le informazioni necessarie per identificare la sessione di un utente vengono inviate al client e nulla è memorizzato sul server. Quando un utente invia una richiesta , il cookie della sessione viene elaborato e convalidato in modo che le rotaie, il custode , escogiti, ecc. Possano capire chi sei e istanziare l'utente corretto dal database da corretto.

Ciò significa che su ogni richiesta, Rails guardare il cookie di sessione, decodificarlo e ottenere qualcosa di simile

cookie = { 
    "session_id": "Value", 
    "_csrf_token": "token", 
    "user_id": "1" 
} 

A quel Rails punto sa che l'utente corrente ha id=1 e CAN fai una query sql. (Come current_user = User.find(1)).

Quando un utente ha effettuato l'accesso, viene creato un cookie, quando l'utente viene disconnesso, il cookie viene distrutto. Se Rails non trovare un biscotto o il cookie non ha informazioni sull'utente corrente, elaborare assumerà che l'utente non è connesso a (current_user è nil)

Anche se si effettua il login tramite ajax (per essere particolare è attraverso la gemma 'angular_devise' nel tuo caso) il cookie viene creato. Non è memorizzato sul server, ma nel browser. (Questo è il motivo per cui se hai effettuato l'accesso in un browser, non sei connesso automaticamente in un altro browser) Come hai sottolineato la libreria non conserva le informazioni di chi ha effettuato l'accesso, e questo perché le informazioni sono memorizzate in un cookie e il la libreria non può decodificare il cookie senza l'aiuto del server.

Questo è il motivo per cui è necessario effettuare una chiamata per ottenere l'utente corrente se l'utente aggiorna la pagina. (Siamo spiacenti)

Il modo per ottenere l'utente corrente è molto semplice. Questa è la soluzione più pulita che ho trovato.

# application_controller.rb 

def me 
    render json: current_user 
end 

# routes.rb 

get "me" => "application#me" 

// main.js 

// I am not familiar with angular_devise lib but you get the point: 
// this method fetches from server when myApp is initialized (e.g. on page reload) 
// and assigns the current_user so he/she can be used by the app 
myApp.run(["AuthService", function(AuthService) { 

    AuthService.getUserFromServer(); 

}]); 

Se è necessario caricare i dati specifici per l'utente, si dovrà caricare l'utente prima e poi i dati. Inutile dire che dovrai usare le promesse.

TL; DR: Si dovrà chiedere al server

Sono aperto per domande e commenti.

1

Immagino che il problema sia l'aggiornamento. Probabilmente la lib di angular-devise presuppone che tu sia in una SPA (Singe Page Application) quindi non dovrebbe aggiornarsi. Con questa ipotesi, l'angular-idea può memorizzare tutte le informazioni in memoria. Quando aggiorni la pagina, esegui fondamentalmente il bootstrap dell'applicazione da zero. E la richiesta al server è probabilmente emessa dal tuo codice all'avvio dell'applicazione. Probabilmente chiami Auth.currentUser() da qualche parte all'avvio dell'applicazione