代码之家  ›  专栏  ›  技术社区  ›  Rich Apodaca

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

  •  4
  • Rich Apodaca  · 技术社区  · 17 年前

    我有一个名为“foo”的资源的RESTfulRails应用程序。我想用 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请求,应该忽略authentitytoken。可能我没有正确使用REST客户机。有什么关于我为什么要例外的想法吗?

    4 回复  |  直到 15 年前
        1
  •  3
  •   Jarrod    17 年前

    尝试将:only=>[:update,:delete,:create]放在应用程序控制器的“防止伪造”行上。

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

        2
  •  2
  •   Rich Apodaca    17 年前

    使用如下内容:

    resource.put '<foo><name>somethingwitty</name></foo>', :content_type => 'application/xml'
    
        3
  •  1
  •   Chris McCauley    17 年前

    我认为你需要做两个改变;

    (A)使用Rails路由将其标记为XML请求 (B)使用HTTP基本身份验证对请求进行身份验证。

    这意味着更改上面的URL以包含用户名和密码,如下所示

    me:secret@localhost: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中的前置过滤器触发。

    另外,我认为您不需要:content_type=>'application/xml'。我通常做的就是打电话或者直接这样…

    response=restclient.post uri.encode(url),:record=>参数

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

    快乐编码

    克里斯

        4
  •  0
  •   joshaidan    15 年前

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

    类似:

    require 'active_resource'
    
    class Foo < ActiveResource::Base
      self.site = 'http://localhost:3000/'
    end
    
    foo = Foo.new(:name => 'somethingwitty')
    foo.save
    

    您可以了解如何在RDOC上进行身份验证 site .

    推荐文章