2014-06-08 1 views
10

J'utilise la bibliothèque cloudspace angularjs-imagine sur le client. Lorsque j'essaie de me connecter/enregistrer, je reçois une réponse de 200 ok avec l'objet utilisateur brut visible dans la console js chrome. L'actualisation de la page semble perdre cette information même si j'ai supposé que le service stockerait cela à un moment donné, car il possède également des méthodes de déconnexion et currentUser. https://github.com/cloudspace/angular_deviseComment puis-je stocker et définir l'utilisateur sur ce service d'authentification de bibliothèque angularjs imagine? Ou est-ce déjà fait?

Mes questions sont les suivantes:

1) Est-ce service de stockage en fait l'utilisateur et si oui, comment (à savoir avec les cookies ou localStorage ou en mémoire)? 2) Si le service ne stocke pas l'utilisateur, comment puis-je stocker ces informations dans un cookie/localstorage personnalisé et, plus important encore, définir l'utilisateur dans le service afin que les méthodes "isauthenticated" et "currentuser" puissent être utilisées ?

Instructions Bibliothèque partielle Readme

enregistrer juste en tant que dépendance Concevoir pour votre module. Ensuite, le service Auth sera disponible pour utilisation. Auth.login (creds): Auth.login() pour s'authentifier auprès du serveur. Auth.login (creds): Auth.login(): Authentification avec le serveur. Gardez à l'esprit que les informations d'identification sont envoyées en clair; utilisez une connexion SSL pour les sécuriser. creds est un objet qui doit contenir toutes les informations d'identification nécessaires pour s'authentifier auprès du serveur. Auth.login() renverra une promesse qui sera résolue à l'utilisateur connecté. Voir AuthProvider.parse() pour analyser l'utilisateur dans un objet utilisable.

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... 
     }); 
    }); 

Mon code partiel:

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

Ma meilleure estimation est que vous devez utiliser le remember_me sur afin de créer un cookie permanent au lieu d'un cookie de session. –

+1

Une idée de comment faire cela à travers l'API? J'envoie généralement une requête POST avec les données utilisateur à '/users/sign_in.json'. Quelles informations puis-je ajouter à la demande de remember_me? –

Répondre

4

Tout d'abord, vous devez comprendre comment les cookies et sessions de travail dans Des rails.

De this article:

Rails utilise un magasin de cookies pour gérer les sessions. Ce que cela signifie, c'est que toutes les informations nécessaires pour identifier la session d'un utilisateur sont envoyées au client et rien n'est stocké sur le serveur. Lorsqu'un utilisateur envoie une demande , le cookie de la session est traité et validé afin que les rails, warden, legs, etc. puissent déterminer qui vous êtes et instancier l'utilisateur correct de la base de données.

Ce que cela signifie est que sur chaque demande, Rails regarder le cookie de session, le décoder et obtenir quelque chose comme

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

À ce moment Rails sait que l'utilisateur actuel a id=1 et peut faire une requête SQL. (Comme current_user = User.find(1)).

Lorsqu'un utilisateur est connecté, un cookie est créé, lorsque l'utilisateur est déconnecté - le cookie est détruit. Si Rails ne trouve pas de cookie ou si le cookie n'a pas d'informations sur l'utilisateur actuel, il supposera que l'utilisateur n'est pas connecté (current_user est)

Même si vous vous connectez via ajax (pour être particulier c'est à travers la gemme 'angular_devise' dans votre cas) que le cookie est créé. Il n'est pas stocké sur le serveur, mais dans le navigateur. (C'est pourquoi si vous êtes connecté dans un navigateur, vous n'êtes pas automatiquement connecté dans un autre navigateur) Comme vous l'avez souligné la bibliothèque ne conserve pas les informations qui sont connectées, et c'est parce que les informations sont stockées dans un cookie et le La bibliothèque ne peut pas décoder le cookie sans l'aide du serveur.

C'est pourquoi vous devrez passer un appel pour obtenir l'utilisateur actuel si l'utilisateur actualise la page. (Désolé)

La façon d'obtenir current_user est très simple. C'est la solution la plus propre que j'ai trouvée.

# 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(); 

}]); 

Si vous devez charger des données spécifiques à l'utilisateur, vous devrez d'abord charger l'utilisateur, puis les données. Inutile de dire que vous devrez utiliser des promesses.

TL; DR: Vous devrez demander au serveur

Je suis ouvert aux questions et commentaires.

1

Je suppose que votre problème est l'actualisation. La bibliothèque angulaire-concevoir est probablement supposant que vous êtes dans un SPA (application de page singulière) donc il ne devrait pas actualiser. Avec cette hypothèse, l'angulaire peut stocker toutes les informations en mémoire. Lorsque vous actualisez votre page, vous faites essentiellement démarrer l'application à partir de zéro. Et la demande au serveur est probablement émise par votre code au démarrage de l'application. Vous appelez probablement Auth.currentUser() quelque part au début de l'application

1

J'ai eu le même problème. Il suffit d'utiliser cette gemme https://github.com/jsanders/angular_rails_csrf Vous pouvez également vous débarrasser de "protect_from_forgery" dans votre contrôleur d'application, mais c'est très risqué.

Questions connexes