الاتصال بالجلسة في Java و Python. HttpURLConnection و CookieManager (Java). الطلبات (Python)

لنفترض أننا بحاجة إلى الاتصال بالخادم وتسجيل الدخول ودعم الجلسة. في المتصفح يبدو كالتالي:



  1. يتم إرسال طلب GET فارغ إلى العنوان http: // localhost: 8080 / login .
  2. يرسل الخادم نموذجًا لملء اسم المستخدم وكلمة المرور ، ويرسل أيضًا ملف تعريف ارتباط بالشكل "JSESSIONID = 094BC0A489335CF8EE58C8E7846FE49B".
  3. بعد ملء اسم المستخدم وكلمة المرور ، يتم إرسال طلب POST إلى الخادم مع استلام ملف تعريف الارتباط في وقت سابق ، مع السطر في دفق الإخراج "username = Fox & password = 123". تنص الرؤوس أيضًا على "نوع المحتوى: application / x-www-form-urlencoded".
  4. ردًا على ذلك ، يرسل الخادم إلينا ملف تعريف ارتباط جديدًا يحتوي على "JSESSIONID =" جديد. تتم إعادة توجيهه على الفور إلى http: // localhost: 8080 / عن طريق طلب GET باستخدام ملف تعريف ارتباط جديد.
  5. بعد ذلك ، يمكنك استخدام بقية واجهة برمجة تطبيقات الخادم بأمان ، وتمرير آخر ملف تعريف ارتباط في كل طلب.


دعونا نرى كيف يمكن تنفيذ ذلك في Java و Python.







المحتوى





تنفيذ بايثون. الطلبات



عند اختيار مكتبة للعمل مع شبكة في Python ، ستوصي معظم المواقع بمكتبة الطلبات التي تبرر شعارها بالكامل:

HTTP للبشر
يتم حل المشكلة برمتها بواسطة البرنامج النصي التالي:



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) #


لاحظ أن معالجة ملفات تعريف الارتباط وإعادة التوجيه تحدث تحت الغطاء ، تمامًا كما هو الحال في المتصفح. يمكن أيضًا ملاحظة أنه إذا قمت بإنشاء جلسة عمل متغيرة أخرى 2 ، فيمكنك الحفاظ على اتصالين نشطين في وقت واحد.



تطبيق Java و HttpURLConnection و CookieManager



يؤدي البحث عن مكتبة للتواصل في Java إلى عدة مكتبات في وقت واحد.



على سبيل المثال ، java.net و Apache HttpClient و OkHttp3 .



استقرت على HttpURLConnection (java.net). مزايا هذه المكتبة هي أنها مكتبة " خارج الصندوق " ، وأيضًا ، إذا كنت بحاجة إلى كتابة تطبيق لنظام android ، فإن الموقع الرسمي لديه وثائق . الجانب السلبي هو كمية كبيرة جدًا من التعليمات البرمجية. (بعد بايثون ، إنه مجرد ألم.)



لذا ، لنبدأ. وفقًا للوثائق ، يمكنك استخدام CookieManager للعمل مع الجلسات :



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


ما يجب ملاحظته باستخدام هذا النهج:



  • يشير "CookiePolicy.ACCEPT_ALL" إلى العمل مع جميع ملفات تعريف الارتباط.
  • لن يتم استخدام متغير cookieManager في أي مكان آخر. يتحكم في جميع الاتصالات ، وإذا كان من الضروري الحفاظ على العديد من الجلسات النشطة ، فسيكون من الضروري تغيير ملف تعريف الارتباط في هذا المتغير يدويًا.


بالنظر إلى ذلك ، يمكنك الكتابة في سطر واحد:



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


الفقرتان 1 و 2. دعنا ننفذ طلب GET لاستلام ملف تعريف الارتباط الأول:



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);
}


بعد ذلك ، سيحتوي ملف تعريف الارتباط الخاص بنا على ملف تعريف ارتباط من الخادم وسيتم استبداله تلقائيًا في الطلب التالي.



تبدأ المتعة بطلب POST.



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


يلزمك كتابة "نوع المحتوى: application / x-www-form-urlencoded" في الرؤوس.



لماذا يسمى الأسلوب setRequestProperty ، وليس setHeaders (أو addHeaders) مع طريقة getHeaderField ، لا يزال لغزا.



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


يأتي بعد ذلك الرمز ، وهو غير واضح لأسباب عدم وضعه تحت غطاء المكتبة.



con.setDoOutput(true);


مطلوب هذا السطر من التعليمات البرمجية لفتح الدفق الصادر. من المضحك أنه بدون هذا الخط نحصل على الرسالة التالية:



استثناء في java.net.ProtocolException في الموضوع "الرئيسي": لا يمكن الكتابة إلى URLConnection إذا doOutput = false - استدعاء setDoOutput (true)

نفتح الدفق الصادر ونكتب تسجيل الدخول وكلمة المرور هناك:



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


يبقى قراءة الرد من طلب تمت إعادة توجيهه بالفعل.



تنفيذ Java ، HttpURLConnection بدون CookieManager



يمكنك تنفيذه بدون CookieManager والتحكم في حركة ملفات تعريف الارتباط بنفسك.

الفقرتان 1 و 2. نقوم بإخراج ملف تعريف الارتباط.



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];
}


بعد ذلك ، نرسل طلب POST ، هذه المرة فقط من خلال إدراج ملف تعريف الارتباط وتعطيل إعادة التوجيه التلقائي ، منذ ذلك الحين قبل ذلك ، تحتاج إلى وقت لسحب ملف تعريف ارتباط جديد:



//  
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];


بعد ذلك ، نضيف ببساطة السطر التالي إلى جميع الطلبات:



con.setRequestProperty("Cookie", cookie2);


اتمنى ان تكون مفيدة ترحب التعليقات بخيارات أبسط.



All Articles