rails – “警告:无法validationjsondevise请求的CSRF令牌真实性”
如何检索CSRF令牌以传递JSON请求?
我知道,出于安全原因, Rails正在检查所有请求types(包括JSON / XML)上的CSRF令牌 。
我可以把我的控制器skip_before_filter :verify_authenticity_token
,但我会失去CRSF保护(不build议:-))。
这个类似(仍然没有被接受)的答案暗示了
使用
<%= form_authenticity_token %>
检索标记
问题是如何? 我是否需要先打电话给我的任何页面来检索令牌,然后与Devise进行真正的身份validation? 或者它是我可以从我的服务器获得的一次性信息,然后一直使用(直到我手动在服务器上更改它)?
编辑 :
在Rails 4中,我现在使用@genkilabs在下面的注释中提出的build议:
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format == 'application/json' }
其中,不是完全closures内置的安全性,而是在没有CSRF令牌的情况下击中服务器时可能会存在的任何会话。
skip_before_filter :verify_authenticity_token, :if => Proc.new { |c| c.request.format == 'application/json' }
这将closures已正确标记的jsonpost/ puts的CSRF检查。
例如,在iOS中将以下参数设置为您的NSURLRequest,其中“参数”是您的参数:
[request setHTTPMethod:@"POST"]; [request setValue:@"application/json" forHTTPHeaderField:@"content-type"]; [request setValue:@"application/json" forHTTPHeaderField:@"accept"]; [request setHTTPBody:[NSData dataWithBytes:[parameters UTF8String] length:[parameters length]]];
您可以在成功login后使用自定义标题发送CSRF令牌。
例如,把这个放在你的会话中#create:
response.headers['X-CSRF-Token'] = form_authenticity_token
提供CSRF令牌的示例login响应头文件:
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
此令牌在您再次login之前是有效的,或者(如果您通过API支持,则注销)。 您的客户端可以从login响应头中提取并存储令牌。 然后,每个POST / PUT / DELETE请求必须使用在login时收到的值设置X-CSRF-Token标头。
使用CSRF令牌的POST标题示例:
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=
文档: form_authenticity_token
确实是最简单的方法。 不要打扰改变标题。
确保你有:
<%= csrf_meta_tag %>
在你的layouts/application.html.erb
只要做一个隐藏的input字段,如下所示:
<input name="authenticity_token" type="hidden" value="<%= form_authenticity_token %>"/>
或者,如果你想要一个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); } });
基本上,当你发布你的json数据只是添加一个有效的authenticity_token领域的post
数据和警告应该消失…
我这样解决了这个错误:
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
来源: http : //api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html
令人担忧的是,在Rails 3.2.3中,我们现在在production.log中获得CSRF警告,但是post并没有失败! 我希望它失败,因为它可以保护我免受攻击。 你可以在jQuery中添加csrf标记之前筛选btw:
我已经使用了下面。 使用include? 所以如果内容types是application / json; charset = utf-8那么它仍然在工作。
protect_from_forgery with: :null_session, if: Proc.new { |c| c.request.format.include? 'application/json' }
这个答案比较好。
在任何XMLHttpRequest发送之前,您都可以保持CSRF-TOKENvalidation无需额外的工作(该标记被追加)。 没有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); }; }());
我有与以下版本的Rails相同的问题:
gem'rails',:git =>'git://github.com/rails/rails.git',:branch =>'3-2-stable'
我更新到3.2.2,现在一切正常。 🙂
gem轨“,”3.2.2“
今天晚上我遇到了同样的问题。 发生的原因是因为当你login时,最后一个csrf-token不再有效。 我做的是: $("meta[name=csrf-token]").attr('content', '<%= form_authenticity_token %>');
在你的app / views / devise / sessions / create.js.rb中。
现在它有一个有效的csrf令牌:)我希望它可以帮助
也用于开发/testing模式。
protect_from_forgery with: :exception unless %w(development test).include? Rails.env
此警告显示,因为您正在使用:null_session
,在Rails 4.1中它默认工作,如果没有with:
指定的选项。
protect_from_forgery
这不是一个错误。 它应该检查每个非GET请求。 https://github.com/rails/rails/issues/3041