一个解决方案是将授权令牌作为变量存储在您的应用程序中。例如,
// app.js
var app = {
views: {},
models: {},
collections: {},
routers: {},
utils: {},
adapters: {},
session: {}
};
当用户登录时,服务器将发送Devise.friendly_token回客户端。您可以将该访问令牌保存在应用程序中,并保护您免受CSRF攻击。但是,如果攻击者可以访问用户的浏览器,则该方法会向您提供其他类型的攻击。
// LoginView.js
app.views.LoginView = Backbone.View.extend({
// ...
login: function(event){
var data = new FormData();
data.append('email', $('#email').val());
data.append('password', $('#password').val());
$.ajax({
url: API_ROOT + "api/v1/login",
data: data,
type: 'POST',
success: function(data){
app.session.userEmail = data.email;
app.session.userAccessToken = data.access_token;
},
error: function(data){
alert('Login failed');
}
});
},
// ...
});
一旦存储了令牌,就会将其发送到您的API服务器请求的授权头中。
Backbone.sync = function(method, model, options) {
// ... override the Backbone.sync function. See the annotated source code for more
// info.
options.beforeSend = function(xhr) {
xhr.setRequestHeader('Authorization', ("" + app.session.userAccessToken));
}
//... also send for POST
if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
params.type = 'POST';
if (options.emulateJSON) params.data._method = type;
var beforeSend = options.beforeSend;
options.beforeSend = function(xhr) {
xhr.setRequestHeader('X-HTTP-Method-Override', type);
xhr.setRequestHeader('Authorization', ("" + app.session.userAccessToken));
if (beforeSend) return beforeSend.apply(this, arguments);
};
}
//...
};
这种方法远非完美,因为它允许攻击者访问浏览器来获取用户的访问令牌。添加额外安全层的一种方法可能是在服务器端的间隔之后更新访问令牌。希望这至少开始一些关于更好的实现方式的讨论。
查看[sessionStorage](https://developer.mozilla.org/en-US/docs/Web/API/Window/sessionStorage)和[localStorage](https://developer.mozilla.org/en -US/docs/Web/API/Window/localStorage)用于持久性存储的API。 – 2015-02-23 22:05:11