ruby-on-rails - 如何在这个 angularjs 设计库身份验证服务上存储和设置用户?还是已经完成了?

标签 ruby-on-rails angularjs devise

我在客户端上使用 cloudspace angularjs-devise 库。当我尝试登录/注册时,我得到一个 200 ok 响应,并且在 chrome js 控制台中可以看到普通的用户对象。刷新页面似乎会丢失这些信息,即使我假设该服务会在某个时候存储它,因为它也有 logout 和 currentUser 方法。
https://github.com/cloudspace/angular_devise

我的问题是:

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

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

部分库自述文件说明

只需将 Devise 注册为您的模块的依赖项。然后,Auth 服务将可供使用。

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() 将返回一个将解析给登录用户的 promise 。请参阅 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');

});

session Controller .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 和 session 在 Rails 中是如何工作的。

来自 this文章:

Rails uses a CookieStore to handle sessions. What it means is that all the informations needed to identify a user's session is sent to the client and nothing is stored on the server. When a user sends a request, the session's cookie is processed and validated so rails, warden, devise, etc. can figure out who you are and instantiate the correct user from the database.



这意味着在每个请求上,Rails 都会查看 session cookie,对其进行解码并获得类似
cookie = {
  "session_id": "Value",
  "_csrf_token": "token",
  "user_id": "1"
}

此时 Rails 知道当前用户拥有 id=1并且可以进行sql查询。 (如 current_user = User.find(1) )。

当用户登录时,会创建一个 cookie,当用户注销时 - cookie 会被销毁。如果 Rails 没有找到 cookie 或者 cookie 没有关于当前用户的信息,devise 将假定用户没有登录( current_usernil )

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

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

获取 current_user 的方法很简单。这是我找到的最干净的解决方案。
# 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();

}]);

如果您必须加载特定于用户的数据,则必须先加载用户,然后再加载数据。不用说,你将不得不使用 Promise。

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

我愿意接受问题和评论。

关于ruby-on-rails - 如何在这个 angularjs 设计库身份验证服务上存储和设置用户?还是已经完成了?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24102625/

相关文章:

javascript - 单击提交按钮时按索引迭代数组 Ruby on Rails

javascript - 热线 : How to render two partials for a broadcasted object on to two different pages?

javascript - javascript中两年之间的小时差(闰年)

ruby-on-rails - 为什么 current_user 也可以通过 @current_user 使用 Devise 获得?

ruby-on-rails - Rails : Before process_action callback :authenticate_user! 尚未定义

javascript - 如何在 Rails View Controller 中访问 HTML5 本地存储

ruby-on-rails - 我们如何获取 ActiveRecord 事务中创建/更新/回滚记录的数量

ruby-on-rails - devise-如何向用户模型添加验证

javascript - 自定义具有多个值的工具提示

javascript - 存储来自 AngularJS 输入表单的数据