Jak zaimplementować obsługę plików cookie w ruby net / http?
Chciałbym dodać obsługę plików cookie do klasy ruby wykorzystującej net / http do przeglądania sieci. Pliki cookie muszą być przechowywane w pliku, aby przetrwać po zakończeniu skryptu. Oczywiście, że mogę przeczytać specyfikację i napisać jakiegoś Handlera, użyć ciastka.format txt i tak dalej, ale wydaje się, że oznacza to wynalezienie koła na nowo. Czy istnieje lepszy sposób na wykonanie tego zadania? Może jakieś zajęcia z ciasteczkami?
6 answers
Pobrane z DZone Snippets
http = Net::HTTP.new('profil.wp.pl', 443)
http.use_ssl = true
path = '/login.html'
# GET request -> so the host can set his cookies
resp, data = http.get(path, nil)
cookie = resp.response['set-cookie'].split('; ')[0]
# POST request -> logging in
data = 'serwis=wp.pl&url=profil.html&tryLogin=1&countTest=1&logowaniessl=1&login_username=blah&login_password=blah'
headers = {
'Cookie' => cookie,
'Referer' => 'http://profil.wp.pl/login.html',
'Content-Type' => 'application/x-www-form-urlencoded'
}
resp, data = http.post(path, data, headers)
# Output on the screen -> we should get either a 302 redirect (after a successful login) or an error page
puts 'Code = ' + resp.code
puts 'Message = ' + resp.message
resp.each {|key, val| puts key + ' = ' + val}
puts data
Update
#To save the cookies, you can use PStore
cookies = PStore.new("cookies.pstore")
# Save the cookie
cookies.transaction do
cookies[:some_identifier] = cookie
end
# Retrieve the cookie back
cookies.transaction do
cookie = cookies[:some_identifier]
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-02-25 17:07:06
Zaakceptowana odpowiedź nie będzie działać, jeśli twój serwer powróci i oczekuje wielu plików cookie. Może się to zdarzyć na przykład, jeśli serwer zwróci Zestaw Plików cookie FedAuth [N]. Jeśli ma to wpływ na ciebie, możesz zamiast tego przyjrzeć się użyciu czegoś w następujący sposób:
http = Net::HTTP.new('https://example.com', 443)
http.use_ssl = true
path1 = '/index.html'
path2 = '/index2.html'
# make a request to get the server's cookies
response = http.get(path)
if (response.code == '200')
all_cookies = response.get_fields('set-cookie')
cookies_array = Array.new
all_cookies.each { | cookie |
cookies_array.push(cookie.split('; ')[0])
}
cookies = cookies_array.join('; ')
# now make a request using the cookies
response = http.get(path2, { 'Cookie' => cookies })
end
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-16 22:36:42
Zaakceptowana odpowiedź nie działa. Musisz uzyskać dostęp do wewnętrznej reprezentacji nagłówka odpowiedzi, gdzie wiele wartości set-cookie jest przechowywanych oddzielnie, a następnie usunąć wszystko po pierwszym średniku z tego ciągu i połączyć je razem. Oto kod, który działa
r = http.get(path)
cookie = {'Cookie'=>r.to_hash['set-cookie'].collect{|ea|ea[/^.*?;/]}.join}
r = http.get(next_path,cookie)
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-11 04:29:37
Użyj http-cookie , który implementuje parsowanie i renderowanie zgodne z RFC oraz jar.
Prymitywny przykład, który zdarza się podążać za przekierowaniem po zalogowaniu:
require 'uri'
require 'net/http'
require 'http-cookie'
uri = URI('...')
jar = HTTP::CookieJar.new
Net::HTTP.start(uri.host, uri.port, use_ssl: uri.scheme == 'https') do |http|
req = Net::HTTP::Post.new uri
req.form_data = { ... }
res = http.request req
res.get_fields('Set-Cookie').each do |value|
jar.parse(value, req.uri)
end
fail unless res.code == '302'
req = Net::HTTP::Get.new(uri + res['Location'])
req['Cookie'] = HTTP::Cookie.cookie_value(jar.cookies(uri))
res = http.request req
end
Dlaczego to robisz? Ponieważ powyższe odpowiedzi są niewiarygodnie niewystarczające i nie działają w wielu scenariuszach zgodnych z RFC (zdarzyło mi się), więc poleganie na implementacji lib tylko to, co jest potrzebne, jest nieskończenie solidniejsze, jeśli chcesz obsłużyć więcej niż jeden konkretny przypadek.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-01-25 08:59:41
Użyłem krawężnika i Mechanize do podobnego projektu. Wystarczy włączyć obsługę plików cookie i zapisać pliki cookie na tymczasowym urządzeniu cookiejar... Jeśli używasz net / http lub pakietów bez wbudowanej obsługi plików cookie, musisz napisać własną obsługę plików cookie.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-28 17:35:02
Możesz wysyłać odbiorcze pliki cookie za pomocą nagłówków.
Możesz zapisać nagłówek w dowolnym frameworku persistence. Czy jest to jakaś baza danych, czy pliki.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-09-28 12:21:30