Spi*_*ion 10 ruby-on-rails devise angularjs
我在客户端上使用cloudspace angularjs-devise库.当我尝试登录/注册时,我在chrome js控制台中看到了普通用户对象的200 ok响应.刷新页面似乎丢失了这些信息,即使我假设服务会在某些时候存储它,因为它也有logout和currentUser方法. https://github.com/cloudspace/angular_devise
我的问题是:
1)这项服务是否实际存储了用户,如果是,如何(即使用cookies或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.
});
Run Code Online (Sandbox Code Playgroud)
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...
});
});
Run Code Online (Sandbox Code Playgroud)
我的部分代码:
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');
});
Run Code Online (Sandbox Code Playgroud)
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();
};
}]);
Run Code Online (Sandbox Code Playgroud)
首先,您需要了解 cookie 和会话在 Rails 中如何工作。
从这篇文章:
Rails 使用 CookieStore 来处理会话。这意味着识别用户会话所需的所有信息都将发送到客户端,并且服务器上不会存储任何信息。当用户发送请求时,会话的 cookie 会被处理和验证,因此 Rails、warden、devise 等可以找出您是谁,并从数据库中实例化正确的用户。
这意味着,对于每个请求,Rails 都会查找会话 cookie,对其进行解码并得到类似的内容
cookie = {
"session_id": "Value",
"_csrf_token": "token",
"user_id": "1"
}
Run Code Online (Sandbox Code Playgroud)
此时Rails 知道当前用户已经id=1
并且可以进行sql 查询。(喜欢current_user = User.find(1)
)。
当用户登录时,会创建 cookie;当用户注销时,cookie 会被销毁。如果 Rails 没有找到 cookie 或者 cookie 没有有关当前用户的信息,devise 将假设该用户尚未登录 ( current_user
is nil
)
即使您通过 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();
}]);
Run Code Online (Sandbox Code Playgroud)
如果您必须加载特定于用户的数据,则必须先加载用户,然后再加载数据。不用说你将不得不使用承诺。
TL;DR:你必须询问服务员
我愿意接受提问和评论。
归档时间: |
|
查看次数: |
2067 次 |
最近记录: |