2015-02-23 152 views
1

我开始了Marionette on Rails应用程序,并且正在寻找一种安全的方式来验证请求。我敢肯定,这已被许多这样做,但我无法找到一个满意的答案:(将Auth令牌安全地存储在Backbone应用程序中

这是我到目前为止已经发现:

  • 在轨,我可以生成Devise.friendly_token令牌,将它保存在数据库中,并将其发送给客户端。
  • 客户端可以存储在从CSRF保护的页面的元数据标记。
  • 在每个请求,客户端将发送令牌中标题与

    var token = $("meta[name='csrf-token']").attr("content"); xhr.setRequestHeader("X-CSRF-Token", token);

,服务器会比较令牌验证请求。到现在为止还挺好。

  • 我在不同的地方看过,Cookie容易跨域请求。然而,永久性cookies似乎是永久性会话的唯一解决方案。我怎样才能以安全的方式使用它们?

  • 另一方面,我已经看到,建议在将密码发送到服务器之前在客户端散列密码。对于基于API的服务,这有什么好处?

谢谢!

+0

查看[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

回答

1

一个解决方案是将授权令牌作为变量存储在您的应用程序中。例如,

// 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); 
    }; 
    } 

//... 
}; 

这种方法远非完美,因为它允许攻击者访问浏览器来获取用户的访问令牌。添加额外安全层的一种方法可能是在服务器端的间​​隔之后更新访问令牌。希望这至少开始一些关于更好的实现方式的讨论。

相关问题