将会话参数保存在Cookie中 [英] Save session parameters in cookies
问题描述
我有一个简单的Backbone.js应用程序,它使用 json-server 作为后端.我有一个登录功能,可以从集合中查找用户,但是我不知道如何保存会话.我考虑过将参数存储在cookie中,以后将在每次重定向时对其进行检查.这是我的模型:
I've got a simple Backbone.js app which uses json-server as a backend. I have a function to log in, that finds a user from the collection, but I don't get how will I save my session. I thought about storing a parameter in cookies that later will be checked on every redirect. Here is my model:
var User = Backbone.Model.extend({
defaults: {
login: '',
password: '',
authToken: ''
}
});
这是我的收藏集:
var UserCollection = Backbone.Collection.extend({
url: 'http://localhost:3000/users',
// creates a random token
setToken: function () {
var rand = function () {
return Math.random().toString(36).substr(2)
}
var token = rand() + rand();
this.set({authToken: token});
}
});
这是具有登录功能的视图
And this is the view with login function
var LoginView = Backbone.View.extend({
initialize: function () {
this.collection = new UserCollection();
// template
}
// render function omitted
signIn: function () {
var login = $('#login').val();
var password = $('#password').val();
/**
finds a user within with the values from input fields
inside the collection
*/
if (login && password) {
this.collection.fetch({
data: {
login: login,
password: password
}
});
}
}
});
此函数返回一个包含一个对象的数组,该对象是我请求的模型.我所需要做的就是使用我的setToken
方法并将该模型的authToken
保存在cookie中,以便可以在应用程序中的其他地方使用它,但是我实际上并没有怎么做.
This function returns me an array with one object that is my requested model. All that I need is to use my setToken
method and to save this model's authToken
in cookie so that I could use it elsewhere in app, but I don't actually get how to do that.
推荐答案
使用模型处理身份验证比集合有意义.使模型的职责简单,并只限于一件事.一个模型来处理身份验证,然后一个模型来处理对需要验证的其他对象的调用,而不是一次完成.
Using a model to handle authentication would make more sense than a collection. Keep the model's responsibility simple and scoped to one thing. A model to handle the authentication, then a model to handle calls to other object which needs to be authenticated, not both at once.
我个人基于骨干会话的模型进行身份验证.
I personally based authentication on Backbone-session's model.
// Using CommonJS
var Session = require('backbone-session');
// Extend from Session to implement your API's behaviour
var Account = Session.extend({
urlRoot: 'http://localhost:3000/users',
signIn: function(opt) {
opt = opt || {};
opt.data = _.extend({}, {
login: opt.login,
password: opt.password
}, opt.data);
return this.fetch(opt);
},
signOut: function(opt) { /** handle logout */ },
getAuthStatus: function() { /** handle refetching if needed */ }
});
作为服务公开给我的应用程序.在此session
模块中,我将覆盖Backbone.Sync
,以确保对于任何模型或集合对API的以下每个调用均经过验证.
Which I expose as a service to my application. In this session
module, I override Backbone.Sync
to ensure auth for each following calls to the API for any models or collection.
var mySession = new Account();
Backbone.sync = (function(syncFn) {
return function(method, model, options) {
options = options || {};
var beforeSend = options.beforeSend,
error = options.error;
// Add auth headers
options.beforeSend = function(xhr) {
xhr.setRequestHeader('Authorization', "Bearer " + mySession.get('authToken'));
if (beforeSend) return beforeSend.apply(this, arguments);
};
// handle unauthorized error (401)
options.error = function(xhr, textStatus, errorThrown) {
if (error) error.call(options.context, xhr, textStatus, errorThrown);
if (xhr.status === 401) {
mySession.signOut();
}
};
return syncFn.apply(this, arguments);
};
})(Backbone.sync);
Backbone-session的模型使用本地存储作为后端.自己的 sync
方法被覆盖以使用本地存储,而不是默认的sync
行为.
Backbone-session's model uses the local storage as a backend. Its own sync
method is overriden to use the local storage instead of the default sync
behavior.
sync: function(method, model, options) {
options = options || {};
var url = model.options.url || model.url;
var key = _.isFunction(url) ? url() : '' + url;
var response;
switch (method) {
case 'create':
case 'update':
var data = model.toJSON();
var text = JSON.stringify(data);
response = localStorage.setItem(key, text);
break;
case 'delete':
response = localStorage.removeItem(key);
break;
case 'read':
response = JSON.parse(localStorage.getItem(key));
break;
}
if (_.isFunction(options.success)) {
options.success(response);
}
return Backbone.$.Deferred()
.resolve(response)
.promise();
},
为什么要使用本地存储?
您可以使用此实现,并对其进行最小的更改以改为使用cookie.
Why the local storage?
You could use this implementation and change it minimally to use cookies instead.
对我来说,本地存储是一个更好的选择,因为我的API在另一个域上,并使用CORS启用公共访问. Safari对cookie有所限制.
The local storage was a better option for me since my API is on another domain and uses CORS to enable public access. Safari has limitation on cookies.
Safari还会阻止尚未访问的站点的cookie 直接地.您可以在安全设置中看到.这是默认设置 是接受Cookie":仅来自我访问的网站".
Safari also blocks cookies from sites that haven't been visited directly. You can see in the security settings. It's default setting is Accept cookies: "Only from sites I visit".
这篇关于将会话参数保存在Cookie中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!