无法在Rails中验证CSRF令牌的真实性

8

我正在使用PaypalAdaptive。它能够正确地发送ipn_notification。ipnNotification操作方法如下 -

def ipn_notification
    ipn = PaypalAdaptive::IpnNotification.new
    ipn.send_back(request.raw_post.to_json)

    print "=====================request.raw_post#{request.raw_post}=============="

    if ipn.verified?
        PaymentMailer.notify_unknown(request.raw_post).deliver
    else
        logger.info "IT DIDNT WORK"
    end
    render :nothing => true
end

但是它返回了错误。
WARNING: Can't verify CSRF token authenticity rails

任何关于这个问题的帮助。
3个回答

19

在你的控制器中:

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

对于那些读得比较快并且跳过了重要部分的人(即:这不是客户端发起的POST调用...):

  • 是的,它跳过了一些安全性检查,但是请往下看...

  • 是的,这是外部网站进行POST请求的唯一方式

  • 是的,它是安全的:当接收到来自Paypal或类似机构的调用时,显然您会检查参数和密钥。


答案如果能够解释得更好,那就更好了 ;) - matthias krull
不是因为你的回答太简短我给你打了负分,而是因为你没有解释实现方式带来的安全隐患。你基本上绕过了CSRF保护...这与支付结合使用是一件坏事;) - matthias krull
@apneadiving 这个答案在认证系统中开了一个非常基本和大的安全漏洞。解决这个问题最简单和容易的方法是在请求中设置头部,这样认证就不会被破坏。查看其他答案以了解更多信息。 - Ankur Agarwal
@AnkurAgarwal,当涉及到像OP所说的外部调用时,你是完全错误的。 - apneadiving
如何让PayPal发送正确的标头?你不能。 - hunterp
显示剩余3条评论

15

在不牺牲安全性的前提下解决这个问题的正确方法是:

在您的ajax请求中以头部信息的形式发送csrf令牌值。

var csrfToken = $("meta[name='csrf-token']").attr("content");
$.ajaxSetup({
  headers: {
    'X-CSRF-Token': csrfToken
  }
});

1
@Magnum更好的方法?也许,但遗憾的是,它并没有回答这个问题 - apneadiving 1小时前 - apneadiving
这就是为什么我说它是“更好的方法”,而不是“答案”。 - Grey

4
在你的application.js文件中添加以下这行代码。
//= require jquery_ujs

并尝试。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接