12

我一直在使用 REST API 开发 Rails 应用程序,以便从移动应用程序访问。

它工作得很好。当用户从移动应用程序登录时,他会得到auth_token他在未来对 API 的请求中使用的信息。问题是 API 也可以通过访问路径 /api/v1/... 从 Web 访问,因此,它必须受到 CSRF 的保护。

我有BaseApiController继承自ApplicationControllerprotect_from_forgery启用”的类。这是示例:

class Api::V1::BaseApiController < ApplicationController
  # ...
end

class ApplicationController < ActionController::Base
  protect_from_forgery
  # ...
end

现在,当我对我的 API 执行非 GET 请求时auth_token,我的请求成功完成,但在日志中我可以看到著名的WARNING: Can't verify CSRF token authenticity. 如果我protect_from_forgery从我BaseApiControllerprotect_from_forgery.

我的问题是:如何确保我的 API 保持安全,同时在执行非 GET 请求时删除警告?

这是我想出的解决方案之一,但它看起来更像是一种 hack 并执行一个额外的数据库查询:

class Api::V1::BaseApiController < ApplicationController
  # ...
  def verified_request?
    super || User.where(authentication_token: params['auth_token']).count > 0
  end
end

有关该项目的更多详细信息:Rails 3.2.14、Devise、AngularJS。该项目的源代码可以在这里找到。

4

1 回答 1

8

你可能会看到人们认为 CSRF 不是 API 请求的问题(没有状态开始,那么有什么可以劫持的呢?),所以有些人建议以下内容来简单地消除警告:

skip_before_filter :verify_authenticity_token, :only => [:your_method]

但是,有一些评论说可以text/plain使用各种基于 Flash 和 Java 的方法来提交 CSRF。我相信这是不久前在 Rails 中安装安全补丁的原因:http ://weblog.rubyonrails.org/2011/2/8/csrf-protection-bypass-in-ruby-on-rails/

无论如何,可以在此处找到实际检查真实性令牌的良好解决方案:警告:无法验证 CSRF 令牌真实性轨道

它涉及在您的请求中实际设置标头。

祝你好运!

于 2013-08-22T13:43:55.907 回答