Ruby-on-rails 确保用户使用 cookieStore 和 AngularJS 登录或注销的最佳实践
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17982868/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Best practice for ensure user is logged in or out using cookieStore and AngularJS
提问by randombits
Right now I am building an AngularJS based application on top of Ruby on Rails and using Devise for authentication. I have the server responding properly when a user authenticates successfully and when authentication fails. I guess my question is, using $cookieStore, what's the best practice for knowing if a user is logged in or not? There is a cookie that gets set by Rails called "myapp_session", but that session doesn't necessarily mean a user is logged in. Looking for ideas on how to use AngularJS to keep user online/offline management. I'll still be ensuring that requests that require authorization get authorized by the backend regardless of the solution.
现在我正在 Ruby on Rails 之上构建一个基于 AngularJS 的应用程序,并使用 Devise 进行身份验证。当用户身份验证成功和身份验证失败时,我让服务器正确响应。我想我的问题是,使用 $cookieStore,了解用户是否登录的最佳做法是什么?Rails 设置了一个名为“myapp_session”的 cookie,但该会话并不一定意味着用户已登录。寻找有关如何使用 AngularJS 保持用户在线/离线管理的想法。无论解决方案如何,我仍将确保需要授权的请求得到后端的授权。
回答by Deividi Cavarzan
You can create an directive that set up the logged user when the application loads, for example, requesting the current user session on your server.
您可以创建一个指令,在应用程序加载时设置登录用户,例如,请求服务器上的当前用户会话。
angular.module('Auth', [
'ngCookies'
])
.factory('Auth', ['$cookieStore', function ($cookieStore) {
var _user = {};
return {
user : _user,
set: function (_user) {
// you can retrive a user setted from another page, like login sucessful page.
existing_cookie_user = $cookieStore.get('current.user');
_user = _user || existing_cookie_user;
$cookieStore.put('current.user', _user);
},
remove: function () {
$cookieStore.remove('current.user', _user);
}
};
}])
;
And set in your runmethod in AppController:
并在您的run方法中设置AppController:
.run(['Auth', 'UserRestService', function run(Auth, UserRestService) {
var _user = UserRestService.requestCurrentUser();
Auth.set(_user);
}])
Of course if any request to the server return an Http Status 401 - Unauthorized, you need to call the Auth.remove()service to remove the user from cookie and redirect the user to login page.
当然,如果对服务器的任何请求返回一个Http Status 401 - Unauthorized,则需要调用该Auth.remove()服务将用户从 cookie 中删除并将用户重定向到登录页面。
I use this approach and works very well. You can also use the localStorage, but the user data will be persisted for a long time. Unless you set an expiration date for this authentication, I don't see as best practice.
我使用这种方法并且效果很好。也可以使用localStorage,但是用户数据会被持久化很长时间。除非您为此身份验证设置到期日期,否则我认为这不是最佳实践。
Keep in mind to always verify the user credentials on your server site =)
请记住始终验证您的服务器站点上的用户凭据 =)
[EDIT]
[编辑]
To listen to 401 - Unauthorizedserver response, you can put an interceptor on your $httprequest, like this:
要侦听401 - Unauthorized服务器响应,您可以在$http请求上放置一个拦截器,如下所示:
.config(['$urlRouterProvider', '$routeProvider', '$locationProvider', '$httpProvider', function ($urlRouterProvider, $routeProvider, $locationProvider, $httpProvider) {
$urlRouterProvider.otherwise('/home');
var interceptor = ['$location', '$q', function ($location, $q) {
function success(response) {
return response;
}
function error(response) {
if (response.status === 401) {
$location.path('/login');
return $q.reject(response);
}
else {
return $q.reject(response);
}
}
return function (promise) {
return promise.then(success, error);
};
}];
$httpProvider.responseInterceptors.push(interceptor);
}])
Every call with 401response, the user will be redirected to login page at /loginpath.
每次有401响应的调用,用户将被重定向到/login路径上的登录页面。
You will find a good example here
你会在这里找到一个很好的例子
回答by Zack Argyle
You can set the cookie on your login callback with
您可以在登录回调上设置 cookie
$cookieStore.put('logged-in', some_value)
Then check for it when they enter your site with
然后在他们进入您的网站时检查它
.run(function($cookieStore) {
if ($cookieStore.get('logged-in') === some_value) {
let him enter
}
else {
you shall not pass
}
});
There might be more "correct" ways, but this works.
可能有更多“正确”的方法,但这是有效的。
回答by Maciej Gurban
If you're having problems making the accepted answer work, be wary, that as of Angular 1.3, a proper way of adding a new interceptor is by adding it to $httpProvider.interceptors, so instead of:
如果您在使接受的答案起作用时遇到问题,请注意,从 Angular 1.3 开始,添加新拦截器的正确方法是将其添加到 $httpProvider.interceptors,而不是:
$httpProvider.responseInterceptors.push(interceptor);
use:
用:
$httpProvider.interceptors.push(interceptor);

