Connexion à la session en Java et Python. HttpURLConnection et CookieManager (Java). Demandes (Python)

Disons que nous devons nous connecter au serveur, nous connecter et prendre en charge la session. Dans le navigateur, cela ressemble à ceci:



  1. Une demande GET vide est envoyée à l' adresse http: // localhost: 8080 / login .
  2. Le serveur envoie un formulaire pour remplir l'identifiant et le mot de passe, et envoie également un cookie du formulaire "JSESSIONID = 094BC0A489335CF8EE58C8E7846FE49B".
  3. Après avoir rempli le nom d'utilisateur et le mot de passe, une requête POST est envoyée au serveur avec le cookie reçu plus tôt, avec la ligne dans le flux de sortie "username = Fox & password = 123". Les en-têtes indiquent également «Content-Type: application / x-www-form-urlencoded».
  4. En réponse, le serveur nous envoie un nouveau cookie avec un nouveau "JSESSIONID =". Il redirige immédiatement vers http: // localhost: 8080 / par requête GET avec un nouveau cookie.
  5. De plus, vous pouvez utiliser en toute sécurité le reste de l'API du serveur, en passant le dernier cookie dans chaque demande.


Voyons comment cela peut être implémenté en Java et Python.







Contenu





Implémentation Python. Demandes



Lors du choix d'une bibliothèque de mise en réseau Python , la plupart des sites recommandent la bibliothèque de demandes , qui respecte sa devise:

HTTP pour les humains
L'ensemble de la tâche est résolu par le script suivant:



import requests
session = requests.session()  # 
url = "http://localhost:8080/login"
session.get(url)   # cookie
data = {"username": "Fox", "password": "123"} 
response = session.post(url, data=data) #


Notez que la manipulation des cookies et de la redirection se fait sous le capot, tout comme dans un navigateur. On peut également noter que si vous créez une autre variable session2 , vous pouvez garder deux connexions actives à la fois.



Implémentation Java, HttpURLConnection et CookieManager



La recherche d'une bibliothèque pour la mise en réseau en Java conduit à plusieurs bibliothèques à la fois.



Par exemple java.net , Apache HttpClient et OkHttp3 .



Je me suis installé sur HttpURLConnection (java.net). Les avantages de cette bibliothèque sont qu'il s'agit d'une bibliothèque " prête à l'emploi ", et aussi, si vous avez besoin d'écrire une application pour Android, le site officiel a de la documentation . L'inconvénient est une très grande quantité de code. (Après Python, c'est juste une douleur.)



Commençons donc. Selon la documentation, vous pouvez utiliser le CookieManager pour travailler avec des sessions :



CookieManager cookieManager = new CookieManager(null, CookiePolicy.ACCEPT_ALL);
CookieHandler.setDefault(cookieManager);


Choses à noter en utilisant cette approche:



  • "CookiePolicy.ACCEPT_ALL" indique de travailler avec tous les cookies.
  • La variable cookieManager ne sera utilisée nulle part ailleurs. Il contrôle toutes les connexions, et s'il est nécessaire de maintenir plusieurs sessions actives, il sera nécessaire de modifier manuellement le cookie dans cette seule variable.


Compte tenu de cela, vous pouvez écrire sur une seule ligne:



 CookieHandler.setDefault(new CookieManager(null, CookiePolicy.ACCEPT_ALL));


Paragraphes 1 et 2. Exécutons la requête GET pour recevoir le premier cookie:



URL url = new URL("http://localhost:8080/login");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
final StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
    content.append(inputLine);
}


Après cela, notre cookieManager contiendra le cookie du serveur et le remplacera automatiquement dans la prochaine requête.



Le plaisir commence par une requête POST.



url = new URL("http://localhost:8080/login");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");


Vous devez écrire «Content-Type: application / x-www-form-urlencoded» dans les en-têtes.



Pourquoi la méthode est appelée setRequestProperty et non setHeaders (ou addHeaders) avec la méthode getHeaderField est un mystère.



con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");


Vient ensuite le code, qui n'est pas clair pour quelles raisons ils ne seront pas mis sous le capot de la bibliothèque.



con.setDoOutput(true);


Cette ligne de code est nécessaire pour ouvrir le flux sortant. C'est drôle que sans cette ligne, nous obtenons le message suivant:



Exception dans le thread "main" java.net.ProtocolException: impossible d'écrire dans une URLConnection si doOutput = false - appelez setDoOutput (true)

Nous ouvrons le flux sortant et y notons le login et le mot de passe:



final DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes("username=Fox&password=123");
out.flush();
out.close();


Il reste à lire la réponse d'une requête déjà redirigée.



Implémentation Java, HttpURLConnection sans CookieManager



Vous pouvez l'implémenter sans CookieManager et contrôler vous-même le mouvement du cookie.

Paragraphes 1 et 2. Nous supprimons le cookie.



URL url = new URL("http://localhost:8080/login");
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("GET");
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
final StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
    content.append(inputLine);
String cookie = con.getHeaderField("Set-Cookie").split(";")[0];
}


Ensuite, nous envoyons une demande POST, seulement cette fois en insérant un cookie et en désactivant la redirection automatique, car avant cela, vous devez avoir le temps de retirer un nouveau cookie:



//  
url = new URL("http://localhost:8080/login");
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
// headers  cookie
con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
con.setRequestProperty("Cookie", cookie);
// 
con.setInstanceFollowRedirects(false);
//   
con.setDoOutput(true);
final DataOutputStream out = new DataOutputStream(con.getOutputStream());
out.writeBytes("username=Fox&password=123");
out.flush();
out.close();
//    cookie
BufferedReader in = new BufferedReader(new InputStreamReader(con.getInputStream()));
String inputLine;
final StringBuilder content = new StringBuilder();
while ((inputLine = in.readLine()) != null) {
    content.append(inputLine);
String cookie2 = con.getHeaderField("Set-Cookie").split(";")[0];


Ensuite, nous ajoutons simplement la ligne suivante à toutes les demandes:



con.setRequestProperty("Cookie", cookie2);


J'espère que cela a été utile. Les commentaires sont favorables à des options plus simples.



All Articles