使用cookie进行Ruby Net::HTTP::Get请求

9
我希望能够通过Ruby打开我的stackoverflow.com页面。 并且我希望看到的是已经验证过的页面。
我提取了Google Chrome的usr cookie,并创建了以下代码段:
require 'net/http'
require 'cgi'

url = "http://stackoverflow.com/users/1650525/alex-smolov"
uri = URI(url)
http = Net::HTTP.new(uri.host, 80)
request = Net::HTTP::Get.new(uri.request_uri)

cookie = CGI::Cookie.new("usr", "[my cookie is here]")
request['Cookie'] = cookie
r = http.request(request)
puts r.body

它确实输出了一个页面,但我在那里没有进行身份验证。

在Ruby中使用cookie是否可以进行Net::HTTP::Get请求?

2个回答

10

你需要调用CGI::Cookie.to_s方法。

request['Cookie'] = cookie.to_s
尝试使用/不使用.to_s来执行以下代码。
require 'net/http'
require 'cgi'

uri = URI("http://httpbin.org/cookies")
http = Net::HTTP.new(uri.host, 80)
request = Net::HTTP::Get.new(uri.request_uri)
cookie1 = CGI::Cookie.new('usr', 'blah')
request['Cookie'] = cookie1.to_s # <---
r = http.request(request)
puts r.body

更新

正如其他答案提到的那样,所得字符串是服务器输出结果。你需要去掉; path=部分。

CGI::Cookie.new('usr', 'value').to_s.sub(/; path=$/, '')

非常感谢!它在stackoverflow上仍然无法工作,但可能是因为我使用了错误的cookies。我会解决的。再次感谢! - Alex Smolov

9
接受的答案在我看来是不正确的。 CGI :: Cookie#to_s 生成应该由服务器发送到客户端的字符串,而不是Net :: HTTP应该使用的内容。 这可以很容易地证明:
[1] pry(main)> require 'cgi'
=> true
[2] pry(main)> CGI::Cookie.new('usr', 'value').to_s
=> "usr=value; path="

像这样的代码应该更好地工作。

require 'net/http'
require 'cgi'

uri = URI("http://httpbin.org/cookies")
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
request['Cookie'] = "usr=#{CGI.encode cookie_value}"
r = http.request(request)
puts r.body

如果你有多个cookie存储在哈希中:

h = {'cookie1' => 'val1', 'cookie2' => 'val2'}
req['Cookie'] = h.map { |k,v| "#{k}=#{CGI.encode v}" } .join('; ')

谢谢指出,我没注意到。我更新了答案以解决这个问题。谢谢。 - falsetru
出于好奇,为什么你还坚持使用CGI::Cookie,我并没有看到任何好处,因为你之后仍然需要操作#to_s输出。 - graywolf
这段内容与编程有关。我的意思是使用 to_s 来获取字符串。顺便说一下,使用 CGI::Cookie,你不需要自己调用 CGI.encode。 - falsetru

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