6

最近はこういうことでMechanizeを使っていましたが、他のどこでも使っているTyphoeusを使いたいです。Mechanizeの動作を模倣したいのですが、問題は、サイトにログインして、ログインしたユーザーとしてリクエストを実行したいということです。スクリプトの一般化されたバージョンは次のとおりです。

require 'rubygems'
require 'typhoeus'

GET_URL = 'http://localhost:3000'
POST_URL = "http://localhost:3000/admins/sign_in"
URL = "http://localhost:3000/dashboard"
USERNAME_FIELD = 'admin[email]'
PASSWORD_FIELD = 'admin[password]'
USERNAME = "admin@example.com"
PASSWORD = "my_secret_password"

def merge_cookies_into_cookie_jar(response)                            
  if response.headers_hash['set-cookie'].instance_of? Array
    response.headers_hash['set-cookie'].each do |cookie|
      @cookie_jar << cookie.split('; ')[0]
    end
  elsif response.headers_hash['set-cookie'].instance_of? String
    @cookie_jar << response.headers_hash['set-cookie'].split('; ')[0]
  end        
end

# initialize cookie jar
@cookie_jar = []

# for server to establish me a session
response = Typhoeus::Request.get( GET_URL, :follow_location => true )
merge_cookies_into_cookie_jar(response)                                                   

# like submiting a log in form
response = Typhoeus::Request.post( POST_URL,
                                   :params => { USERNAME_FIELD => USERNAME, PASSWORD_FIELD => PASSWORD },
                                   :headers => { 'Cookie' => @cookie_jar.join('; ') }
                                 )
merge_cookies_into_cookie_jar(response)                                                   

# the page I'd like to get in a first place, 
# but not working, redirects me back to login form with 401 Unauthorized :-(                 
response = Typhoeus::Request.get( URL, 
                                  :follow_location => true,
                                  :headers => { 'Cookie' => @cookie_jar.join('; ') }
                                 )

Cookieはサーバーに送信されますが、何らかの理由でログインしていません。2つの異なるサイトでテストしました(そのうちの1つはRailsアプリケーションの管理でした)。私が間違っていること、またはこの問題に対してより良いまたはより広く適用可能な解決策は何ですか?

4

3 に答える 3

8

これが私が正常に実行できるコードです。

まず、Cookie jarは配列であり、私のコードでは、置換された配列(またはハッシュ)である必要があります。私の実際のアプリでコードを実行すると、GET_URL応答はセッションCookieを返しますが、POST_URL応答はのセッションCookieを返します。

# initialize cookie jar as a Hash
@cookie_jar = {}

各Cookieの名前と値を取得するように解析を調整します。

def merge_cookies_into_cookie_jar(response)
  x =  response.headers_hash['set-cookie']
  case x
  ...
  when String
    x.split('; ').each{|cookie|
      key,value=cookie.split('=', 2)
      @cookie_jar[key]=value
    }
  end
end

クッキージャーは文字列に変換する必要があります:

def cookie_jar_to_s
  @cookie_jar.to_a.map{|key, val| "#{key}=#{val}"}.join("; ")
end

最後に、新しいcookie_jar_to_sを使用するようにヘッダーを変更します。

:headers => { 'Cookie' => cookie_jar_to_s }

ボーナスは、クッキージャーを独自のクラスにすることです。おそらく次のようなものです。

class CookieJar < Hash

  def to_s
    self.to_a.map{|key, val| "#{key}=#{val}"}.join("; ")
  end

  def parse(*cookie_strings)
    cookie_strings.each{|s|
      s.split('; ').each{|cookie|
        key,value=cookie.split('=', 2)
        self.[key]=value
      }
    }
  end

end
于 2012-03-26T06:25:49.703 に答える
4

@joelparkerhendersonのCookieJarを修正しました(ここでは機能していなかったため)。ここに結果があります:

class CookieJar < Hash
  def to_s
    self.map { |key, value| "#{key}=#{value}"}.join("; ")
  end

  def parse(cookie_strings)
    cookie_strings.each { |s|
      key, value = s.split('; ').first.split('=', 2)
      self[key] = value
    }
    self
  end
end

# Use like this:
response = Typhoeus::Request.get("http://www.example.com")
cookies = CookieJar.new.parse(response.headers_hash["Set-Cookie"])
Typhoeus::Request.get("http://www.example.com", headers: {Cookie: cookies.to_s})
于 2012-10-04T07:18:42.450 に答える
1

あなたのサイトはRails偽造保護を使用していますか?

その場合、フォームページを取得すると、RailsはCSRFトークンである非表示フィールドを送信します。

HTMLでは次のようになります。

<input type="hidden" name="csrf" value="abcdef">

フォームを投稿するときは、次の非表示の値を使用する必要があります。

:params => {"csrf" => "abcdef", USERNAME_FIELD => USERNAME, ...

隠しフィールドは、あなたがフォームページをリクエストした人であることをRailsに伝えます。したがって、あなた(そしてあなただけ)は投稿を許可されます。

CSRFに関する私のメモと詳細情報へのリンクは次のとおりです。

http://sixarm.com/about/rails-session-csrf-token-jquery-ajaxprefilter.html

関連するStackOverflowCSRF情報:

http://stackoverflow.com/questions/941594/understand-rails-authenticity-token
于 2012-03-25T21:17:15.873 に答える