Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ruby-on-rails-3/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 3 轨道-“;警告:Can';t验证CSRF令牌的真实性”;为json设计请求_Ruby On Rails 3_Ruby On Rails 3.1_Devise_Csrf - Fatal编程技术网

Ruby on rails 3 轨道-“;警告:Can';t验证CSRF令牌的真实性”;为json设计请求

Ruby on rails 3 轨道-“;警告:Can';t验证CSRF令牌的真实性”;为json设计请求,ruby-on-rails-3,ruby-on-rails-3.1,devise,csrf,Ruby On Rails 3,Ruby On Rails 3.1,Devise,Csrf,如何检索CSRF令牌以与JSON请求一起传递 我知道,出于安全原因,所有请求类型(包括JSON/XML)都是如此 我可以在我的控制器之前跳过\u过滤器:验证\u真实性\u令牌,但我将失去CRSF保护(不建议:-)) 这一类似(仍不被接受)建议 使用 问题是怎么做?我是否需要首先调用我的任何页面来检索令牌,然后使用Desive进行真正的身份验证?或者它是一个一次性的信息,我可以从我的服务器获得,然后一直使用(直到我在服务器上手动更改它)我对以下版本的Rails也有同样的问题: gem'rails'

如何检索CSRF令牌以与JSON请求一起传递

我知道,出于安全原因,所有请求类型(包括JSON/XML)都是如此

我可以在我的控制器
之前跳过\u过滤器:验证\u真实性\u令牌
,但我将失去CRSF保护(不建议:-))

这一类似(仍不被接受)建议

使用


问题是怎么做?我是否需要首先调用我的任何页面来检索令牌,然后使用Desive进行真正的身份验证?或者它是一个一次性的信息,我可以从我的服务器获得,然后一直使用(直到我在服务器上手动更改它)

我对以下版本的Rails也有同样的问题:
gem'rails',:git=>'git://github.com/rails/rails.git',:branch=>“3-2-stable”

我更新到了3.2.2,现在一切都正常了。:)
gem'rails'、'3.2.2'

编辑:

在Rails 4中,我现在使用@genkilabs在下面的评论中建议的内容:

使用::null_会话保护_免受伪造,如果:Proc.new{c | c.request.format=='application/json'}

它不是完全关闭内置安全性,而是在没有CSRF令牌的情况下攻击服务器时,关闭可能存在的任何会话


skip_before_filter:verify_authenticity_token,:if=>Proc.new{| c | c.request.format=='application/json'}

这将关闭已正确标记为json POST/PUT的CSRF检查

例如,在iOS中,将以下内容设置为NSURLRequest,其中“参数”是您的参数:



令人担忧的是,在Rails 3.2.3中,我们现在在production.log中得到了CSRF警告,但post并没有失败!我希望它失败,因为它保护我免受攻击。您可以在筛选之前使用jquery添加csrf令牌,顺便说一句:


成功登录后,您可以使用自定义标头发送CSRF令牌

例如,将此内容放入会话中#创建:

提供CSRF令牌的示例登录响应标头:

HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Connection: Keep-Alive
Content-Length: 35
Content-Type: application/json; charset=utf-8
Date: Mon, 22 Oct 2012 11:39:04 GMT
Etag: "9d719d3b9aabd413c3603e04e8a3933d"
Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-10-12)
Set-Cookie: [cut for readability] 
X-Csrf-Token: PbtMPfrszxH6QfRcWJCCyRo7BlxJUPU7HqC2uz2tKGw=
X-Request-Id: 178746992d7aca928c876818fcdd4c96
X-Runtime: 0.169792
X-Ua-Compatible: IE=Edge
POST /api/report HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate, compress
Content-Type: application/json; charset=utf-8
Cookie: [cut for readability]
Host: localhost:3000
User-Agent: HTTPie/0.3.0
X-CSRF-Token: PbtMPfrszxH6QfRcWJCCyRo7BlxJUPU7HqC2uz2tKGw=
此令牌在您再次登录或(如果您通过API支持,请注销)之前有效。 您的客户端可以从登录响应头中提取和存储令牌。然后,每个POST/PUT/DELETE请求必须使用登录时收到的值设置X-CSRF-Token头

带有CSRF令牌的帖子标题示例:

HTTP/1.1 200 OK
Cache-Control: max-age=0, private, must-revalidate
Connection: Keep-Alive
Content-Length: 35
Content-Type: application/json; charset=utf-8
Date: Mon, 22 Oct 2012 11:39:04 GMT
Etag: "9d719d3b9aabd413c3603e04e8a3933d"
Server: WEBrick/1.3.1 (Ruby/1.9.3/2012-10-12)
Set-Cookie: [cut for readability] 
X-Csrf-Token: PbtMPfrszxH6QfRcWJCCyRo7BlxJUPU7HqC2uz2tKGw=
X-Request-Id: 178746992d7aca928c876818fcdd4c96
X-Runtime: 0.169792
X-Ua-Compatible: IE=Edge
POST /api/report HTTP/1.1
Accept: application/json
Accept-Encoding: gzip, deflate, compress
Content-Type: application/json; charset=utf-8
Cookie: [cut for readability]
Host: localhost:3000
User-Agent: HTTPie/0.3.0
X-CSRF-Token: PbtMPfrszxH6QfRcWJCCyRo7BlxJUPU7HqC2uz2tKGw=

文档:

确实是最简单的方法。不要费心修改标题

确保您有:

<%= csrf_meta_tag %>
或者,如果您想要jquery ajax帖子:

$.ajax({     
    type: 'POST',
    url: "<%= someregistration_path %>",
    data: { "firstname": "text_data_1", "last_name": "text_data2", "authenticity_token": "<%= form_authenticity_token %>" },                                                                                  
    error: function( xhr ){ 
      alert("ERROR ON SUBMIT");
    },
    success: function( data ){ 
      //data response can contain what we want here...
      console.log("SUCCESS, data="+data);
    }
});
$.ajax({
键入:“POST”,
url:“”,
数据:{“firstname”:“text\u data\u 1”,“last\u name”:“text\u data2”,“authenticity\u token”:“},
错误:函数(xhr){
警告(“提交时出错”);
},
成功:函数(数据){
//数据响应可以包含我们想要的内容。。。
console.log(“SUCCESS,data=“+data”);
}
});

基本上,当您发布json数据时,只需在
post
数据中添加一个有效的authenticity_标记字段,警告就会消失…

今晚我遇到了同样的问题。 发生这种情况的原因是,当您登录最后一个csrf令牌时,该令牌不再有效。 我所做的是:
$(“meta[name=csrf-token]”)attr('content','')在你的应用程序中/views/designe/sessions/create.js.rb

现在它确实有一个有效的csrf令牌:)
我希望它对开发/测试模式也有帮助

protect_from_forgery with: :exception unless %w(development test).include? Rails.env
显示此警告是因为您正在使用
:null_session
,在Rails 4.1中,如果未指定
选项,则默认情况下此警告有效

protect_from_forgery

我使用了下面的方法。使用include?因此,如果内容类型是application/json;charset=utf-8,则它仍在工作

protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format.include? 'application/json' }

我这样解决了这个错误:

class ApplicationController < ActionController::Base
  protect_from_forgery
  skip_before_action :verify_authenticity_token, if: :json_request?

  protected

  def json_request?
    request.format.json?
  end
end
class ApplicationController
资料来源: 更好

在任何XMLHttpRequest发送之前,无需额外的努力即可保持CSRF-TOKEN验证(标记已附加)。没有JQuery,什么都没有,只是复制/粘贴和刷新

只需添加此代码

(function() {
    var send = XMLHttpRequest.prototype.send,
        token = $('meta[name=csrf-token]').attr('content');
    XMLHttpRequest.prototype.send = function(data) {
        this.setRequestHeader('X-CSRF-Token', token);
        return send.apply(this, arguments);
    };
}());

谢谢你的建议。我试过了,但仍然有相同的警告
警告:无法验证CSRF令牌的真实性
如果攻击者将该格式标记为“json”,您将面临攻击。这就是Rails根据定义发出警告的原因。我希望我的json能够正确地传递一个令牌,否则在日志中显示警告就可以了。你会受到攻击,这就是为什么他们建议你在关闭过滤器时设置一些其他安全措施的原因。通常,对于API请求,请求者将发送一个API密钥和post数据,然后在执行所需方法之前对其进行验证。在rails 4中,您可以使用::null_session执行以下操作:
Proc.new{c | c.request.format='application/json'
@genkilabs,为rails 4用户添加了答案,谢谢=]我刚才在rails和iOS应用程序中做了两件事:1)我不明白为什么我们在Ruby中混合使用新旧样式的散列语法,所以我控制器中的代码看起来像:
protect_from_fagery with::null_session,if:Proc.new{c | c.request.format='application/json'}
2)与此问题无关,但与从iOS发布JSON相关,因为我使用的是
AFNetworking
,Rails没有自动包装参数,所以我做了以下操作:
manager.requestSerializer=[AFJSONRequestSerializer]IMHO它不应该只在
(function() {
    var send = XMLHttpRequest.prototype.send,
        token = $('meta[name=csrf-token]').attr('content');
    XMLHttpRequest.prototype.send = function(data) {
        this.setRequestHeader('X-CSRF-Token', token);
        return send.apply(this, arguments);
    };
}());