Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/ruby-on-rails/52.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angularjs/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 如何在angularjs Desive library auth服务上存储和设置用户?还是已经完成了?_Ruby On Rails_Angularjs_Devise - Fatal编程技术网

Ruby on rails 如何在angularjs Desive library auth服务上存储和设置用户?还是已经完成了?

Ruby on rails 如何在angularjs Desive library auth服务上存储和设置用户?还是已经完成了?,ruby-on-rails,angularjs,devise,Ruby On Rails,Angularjs,Devise,我正在客户端上使用cloudspace angularjs设计库。当我尝试登录/注册时,我得到一个200 ok的响应,在ChromeJS控制台中可以看到普通用户对象。刷新页面似乎会丢失这些信息,尽管我假设服务会在某个时候存储这些信息,因为它还有logout和currentUser方法。 我的问题是: 1) 此服务是否实际存储用户?如果是,如何存储(即使用cookie或localstorage或内存) 2) 如果服务未存储用户,我如何将此信息存储在自定义cookie/localstorage中,

我正在客户端上使用cloudspace angularjs设计库。当我尝试登录/注册时,我得到一个200 ok的响应,在ChromeJS控制台中可以看到普通用户对象。刷新页面似乎会丢失这些信息,尽管我假设服务会在某个时候存储这些信息,因为它还有logout和currentUser方法。

我的问题是:

1) 此服务是否实际存储用户?如果是,如何存储(即使用cookie或localstorage或内存)

2) 如果服务未存储用户,我如何将此信息存储在自定义cookie/localstorage中,更重要的是将用户设置到服务中,以便使用服务“isauthenticated”和“currentuser”方法

部分库自述说明

只需将Desive注册为模块的依赖项。然后,身份验证服务将可供使用

angular.module('myModule', ['Devise']).
    config(function(AuthProvider) {
        // Configure Auth service with AuthProvider
    }).
    controller('myCtrl', function(Auth) {
        // Use your configured Auth service.
    }); 
Auth.login(creds):使用Auth.login()向服务器进行身份验证。请记住,凭证是以明文形式发送的;使用SSL连接来保护它们。creds是一个对象,它应该包含向服务器进行身份验证所需的任何凭据。Auth.login()将返回一个承诺,该承诺将解析为登录用户。有关将用户解析为可用对象的信息,请参见AuthProvider.parse()

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

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

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');

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


}]);

首先,您需要了解Cookie和会话在Rails中是如何工作的

第条:

Rails使用CookieStore来处理会话。这意味着一切 识别用户会话所需的信息将发送到 客户端,服务器上不存储任何内容。当用户发送 请求时,会处理和验证会话的cookie,以便rails, 典狱长、设计师等可以找出你是谁,并举例说明 从数据库中更正用户

这意味着,在每个请求上,Rails都会查看会话cookie,对其进行解码,并得到如下结果

cookie = {
  "session_id": "Value",
  "_csrf_token": "token",
  "user_id": "1"
}
此时Rails知道当前用户具有
id=1
,可以进行sql查询。(如
current\u user=user.find(1)

当用户登录时,将创建cookie,当用户注销时,cookie将被销毁。如果Rails找不到cookie或cookie没有当前用户的信息,Desive将假定用户未登录(
current\u user
nil

即使您通过ajax登录(尤其是通过您的“angular_Desive”gem),也会创建cookie。它不存储在服务器上,而是存储在浏览器中。(这就是为什么如果您登录到一个浏览器,您不会自动登录到另一个浏览器)正如您所指出的,库不会保留登录者的信息,这是因为信息存储在cookie中,如果没有服务器的帮助,库无法解码cookie

这就是为什么如果当前用户刷新页面,您必须进行调用才能获取该用户。(对不起)

获取当前用户的方法非常简单。这是我找到的最干净的解决方案

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

}]);
如果必须加载特定于用户的数据,则必须先加载用户,然后加载数据。不用说,你将不得不使用承诺

TL;DR:您必须询问服务器


我愿意接受提问和评论。

我想你的问题在于刷新。angular Desive库可能假设您在SPA(单页应用程序)中,因此它不应该刷新。有了这个假设,角度装置就可以把所有的信息存储在内存中。刷新页面时,基本上是从零开始引导应用程序。对服务器的请求可能是在应用程序启动时由您的代码发出的。您可能在应用程序启动时的某个地方调用了
Auth.currentUser()
,也有同样的问题。就用那块宝石吧
您还可以在应用程序控制器中消除“防止伪造”,但这是非常危险的。

我的最佳猜测是,您需要使用“记住我”设计,这样它将创建一个永久性cookie,而不是会话cookie。您知道如何通过api实现这一点吗?我通常将带有用户数据的POST请求发送到“/users/sign_in.json”。我可以在“记住我”请求中添加哪些信息?