47 votes

Comment implémenter le support des cookies dans ruby net / http?

J'aimerais ajouter la prise en charge des cookies à une classe ruby utilisant net / http pour naviguer sur le Web. Les cookies doivent être stockés dans un fichier pour survivre après la fin du script. Bien sûr, je peux lire les spécifications et écrire un gestionnaire, utiliser un format cookie.txt, etc., mais cela semble vouloir dire qu'il faut réinventer la roue. Y a-t-il une meilleure façon d'accomplir cette tâche? Peut-être une sorte de classe de bocaux pour traiter les cookies?

42voto

mamills Points 928

La réponse acceptée ne fonctionnera pas si votre serveur renvoie et attend plusieurs cookies. Cela peut arriver, par exemple, si le serveur renvoie un ensemble de cookies FedAuth [n]. Si cela vous concerne, vous voudrez peut-être utiliser quelque chose comme ce qui suit:

 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
 

33voto

khelll Points 12222

Tiré de 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
 

mise à jour

 #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
 

12voto

akuhn Points 12241

La réponse acceptée ne fonctionne pas. Vous devez accéder à la représentation interne de l'en-tête de réponse où les valeurs multiples de cookie set sont stockées séparément, puis tout supprimer après le premier point-virgule de cette chaîne et les joindre. Voici le code qui fonctionne

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

3voto

CodeJoust Points 2867

J'ai utilisé Curb et Mechanize pour un projet similaire. Activez simplement la prise en charge des cookies et enregistrez-les dans un cookiejar temporaire ... Si vous utilisez net / http ou des packages sans prise en charge intégrée des cookies, vous devez écrire votre propre gestion des cookies.

1voto

Matthew Schinckel Points 15596

Vous pouvez envoyer des cookies à l'aide d'en-têtes.

Vous pouvez stocker l'en-tête dans n'importe quel framework de persistance. Que ce soit une sorte de base de données, ou des fichiers.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X