【问题标题】:Store Auth Token securely in Backbone app在 Backbone 应用程序中安全地存储 Auth Token
【发布时间】:2015-02-23 05:00:17
【问题描述】:

我正在启动一个 Marionette on Rails 应用程序,我正在寻找一种安全的方式来验证请求。我敢肯定很多人都这样做过,但我找不到令人满意的答案:(

这是我目前发现的:

  • 在rails中,我可以用Devise.friendly_token生成一个token,保存在数据库中并发送给客户端。
  • 客户端可以将令牌存储在受 CSRF 保护的页面的元数据中。
  • 在每个请求中,客户端都会在标头中发送令牌

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

并且服务器将比较令牌以验证请求。到目前为止一切顺利。

  • 我在不同的地方了解到 cookie 容易受到跨域请求的攻击。然而,持久 cookie 似乎是持久会话的唯一解决方案。如何以安全的方式使用它们?

  • 另一方面,我看到建议在将密码发送到服务器之前在客户端对密码进行哈希处理。对于基于 API 的服务,这样做有什么好处?

谢谢!

【问题讨论】:

标签: ruby-on-rails authentication backbone.js token marionette


【解决方案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);
    };
  }

//...
};

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

【讨论】:

    猜你喜欢
    • 2021-02-09
    • 1970-01-01
    • 2016-05-18
    • 2023-03-28
    • 2019-04-01
    • 2021-05-02
    • 2020-09-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多