首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >rails - json devise请求的“警告:无法验证CSRF令牌的真实性”

rails - json devise请求的“警告:无法验证CSRF令牌的真实性”
EN

Stack Overflow用户
提问于 2012-02-20 22:40:00
回答 10查看 86.8K关注 0票数 82

如何检索要与JSON请求一起传递的CSRF令牌?

我知道出于安全原因,所有请求类型(包括JSON/XML)都使用Rails is checking the CSRF token

我可以放入我的控制器skip_before_filter :verify_authenticity_token,但我会失去CRSF保护(不建议:-)。

这个类似的(仍未被接受) answer建议

使用<%= form_authenticity_token %>检索令牌

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

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2012-04-07 06:28:45

编辑

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

protect_from_forgery with: :null_session, if: 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 posts/puts的CSRF检查。

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

代码语言:javascript
复制
[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]]];
票数 128
EN

Stack Overflow用户

发布于 2012-10-22 20:04:04

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

例如,把这个放到你的sessions#create中:

代码语言:javascript
复制
response.headers['X-CSRF-Token'] = form_authenticity_token

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

代码语言:javascript
复制
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

此令牌在您重新登录或(如果您通过API支持则注销)之前一直有效。您的客户端可以从登录响应标头中提取并存储令牌。然后,每个POST/PUT/DELETE请求都必须用登录时收到的值设置X-CSRF-Token标头。

使用CSRF令牌的示例帖子标头:

代码语言:javascript
复制
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

票数 18
EN

Stack Overflow用户

发布于 2013-05-06 21:05:58

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

确保您拥有:

代码语言:javascript
复制
<%= csrf_meta_tag %>

在你的layouts/application.html.erb

只需像这样做一个隐藏的输入字段:

代码语言:javascript
复制
<input name="authenticity_token" 
       type="hidden" 
       value="<%= form_authenticity_token %>"/>

或者如果你想要一篇jquery ajax文章:

代码语言:javascript
复制
$.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数据时,只需向post数据添加一个有效的authenticity_token字段,警告就会消失……

票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/9362910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档