Ruby的REST客户端提供ActionController :: InvalidAuthenticityToken

时间:2009-05-07 05:05:57

标签: ruby-on-rails ruby rest

我有一个RESTful Rails应用程序,其资源名为“Foo”。我正在尝试使用REST Client来做放置:

resource = RestClient::Resource.new 'http://localhost:3000/foos/1', :user => 'me', :password => 'secret'
resource.put :name => 'somethingwitty', :content_type => 'application/xml'

但是我的应用提出了:

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
/usr/lib/ruby/gems/1.8/gems/actionpack-2.2.2/lib/action_controller/request_forgery_protection.rb:86:in `verify_authenticity_token'

似乎我的应用程序没有收到消息,这是一个XML请求,并且应该忽略AuthenticityToken。也许我没有正确使用REST Client。关于为什么我得到例外的任何想法?

4 个答案:

答案 0 :(得分:3)

尝试输入:only =>应用程序控制器中protect_from_forgery行上的[:update,:delete,:create]。

更多信息:http://ryandaigle.com/articles/2007/9/24/what-s-new-in-edge-rails-better-cross-site-request-forging-prevention

答案 1 :(得分:2)

使用类似:

resource.put '<foo><name>somethingwitty</name></foo>', :content_type => 'application/xml'

答案 2 :(得分:1)

我认为您需要进行两项更改;

(a)使用rails routing将其标记为XML请求 (b)使用HTTP基本身份验证来验证请求。

这意味着更改上面的网址以包含用户名,密码,例如

我:秘密@本地:3000 / FOOS / 1.XML

还要注意.xml位

我猜你服务器端的某个地方有代码通过before过滤器验证入站请求。这需要像这样工作......

#
#  If you haven't authenticated already then you are either
#  reqirected to the logon screen (for HTML formats) or 
#  the browser prompts you. You are always allowed to pass 
#  the username/password in the URL
#
def login_required
    @current_user = valid_session?

    unless @current_user
        if params["format"]
            #
            #   If you specify a format you must authenticate now
            # 
            do_basic_authentication
        else
            display_logon_screen
        end
    end
end


#
#   Ask Rails for the login and password then authenticate as if this
#   were a new login.
#
def do_basic_authentication
    user = authenticate_with_http_basic do |login, password|
        User.authenticate(login, password)
    end

    if user
        current_user(@current_user = user)
    else
        request_http_basic_authentication
    end
end

这是来自我们自己的应用程序,由ApplicationController中的before_filter触发。

另外,我认为你不需要:content_type =&gt; '应用程序/ XML'。我通常做的只是打电话或直接放这样..

response = RestClient.post URI.encode(url),:record =&gt; ARGS

其中url包含基本身份验证和“.xml”

快乐编码

克里斯

答案 3 :(得分:0)

由于您的应用程序是Rails应用程序,因此为客户端使用ActiveResource可能更容易。

类似的东西:

require 'active_resource'

class Foo < ActiveResource::Base
  self.site = 'http://localhost:3000/'
end

foo = Foo.new(:name => 'somethingwitty')
foo.save

您可以阅读有关如何在rdoc site上进行身份验证的信息。