Domanda Come implementare il supporto dei cookie in ruby ​​net / http?


Mi piacerebbe aggiungere il supporto dei cookie a una classe ruby ​​che utilizza net / http per navigare sul web. I cookie devono essere memorizzati in un file per sopravvivere dopo che lo script è terminato. Naturalmente posso leggere le specifiche e scrivere un qualche tipo di gestore, utilizzare alcuni formati cookie.txt e così via, ma sembra voler dire reinventare la ruota. C'è un modo migliore per realizzare questo compito? Forse una specie di classe di ghiottaio per prendersi cura dei biscotti?


44
2017-09-28 12:06


origine


risposte:


Preso da Frammenti DZone

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

aggiornare

#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

34
2017-09-28 12:26



La risposta accettata non funzionerà se il tuo server ritorna e si aspetta più cookie. Ciò potrebbe accadere, ad esempio, se il server restituisce un set di cookie FedAuth [n]. Se questo ti riguarda, potresti voler usare qualcosa seguendo le linee di seguito:

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

40
2018-02-16 22:36



La risposta accettata non funziona. È necessario accedere alla rappresentazione interna dell'intestazione di risposta in cui i valori multipli di cookie di set sono negozi separatamente e quindi rimuovere tutto dopo il primo punto e virgola da questa stringa e unirli insieme. Ecco il codice che funziona

r = http.get(path)
cookie = {'Cookie'=>r.to_hash['set-cookie'].collect{|ea|ea[/^.*?;/]}.join}
r = http.get(next_path,cookie)

12
2018-05-11 04:29



Uso http-cookie, che implementa analisi e rendering compatibili con RFC, oltre a un jar.

Un esempio grezzo che segue un post-login di reindirizzamento:

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

Perché questo? Poiché le risposte di cui sopra sono incredibilmente insufficienti e piatte non funzionano in molti scenari RFC (è successo a me), quindi affidarsi alla lib di implementare solo ciò che è necessario è infinitamente più robusto se si desidera gestire più di un caso particolare .


5
2017-09-30 14:21



Ho usato Curb e Mechanize per un progetto simile. Basta abilitare i cookie per il supporto e salvare i cookie su un cookie temporaneo ... Se stai usando net / http o pacchetti senza supporto cookie integrato, dovrai scrivere la tua gestione dei cookie.


3
2017-09-28 17:35



Puoi inviare i cookie di ricezione utilizzando le intestazioni.

È possibile memorizzare l'intestazione in qualsiasi framework di persistenza. Che si tratti di una sorta di database o di file.


1
2017-09-28 12:21