العودة إلى المدونة

كيفية إصلاح مشاكل ملفات تعريف الارتباط عبر الوكيل

ملفات تعريف الارتباط غالباً ما تسبب مشاكل عند العمل عبر وكيل. تعرف على السبب وكيفية تكوينها بشكل صحيح.

📅١٧ جمادى الآخرة ١٤٤٧ هـ
```html

كيفية إصلاح مشاكل ملفات تعريف الارتباط عبر الوكيل

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

لماذا تضيع ملفات تعريف الارتباط عند استخدام الوكيل

عندما تُرسل طلباً عبر وكيل، يظهر عقدة وسيطة بين عميلك والخادم المستهدف. يؤدي هذا إلى عدة مشاكل:

  • عناوين IP مختلفة لجلسة واحدة. قد يلاحظ الخادم أن الطلبات تأتي من عناوين مختلفة ويرفض ملفات تعريف الارتباط كمريبة.
  • فقدان رؤوس Set-Cookie. قد لا تنقل الإعدادات غير الصحيحة للوكيل رؤوس Set-Cookie إلى العميل.
  • عدم تطابق النطاق والمسار. إذا أعاد الوكيل كتابة رأس Host، فقد لا يتم حفظ ملفات تعريف الارتباط بسبب عدم تطابق النطاق.
  • عدم وجود حفظ للحالة. إذا أرسلت كل طلب بشكل منفصل دون حفظ ملفات تعريف الارتباط، ستُفقد الجلسة.

Cookie jar هو مستودع لملفات تعريف الارتباط يدير إرسالها واستقبالها تلقائياً. بدلاً من إضافة رؤوس Cookie يدويًا في كل طلب، تسمح للمكتبة بفعل ذلك تلقائياً.

تحتوي معظم عملاء HTTP على دعم مدمج لـ cookie jar:

import requests
from requests.cookies import RequestsCookieJar

# ننشئ jar لتخزين ملفات تعريف الارتباط
jar = RequestsCookieJar()

# الطلب الأول — سيرسل الخادم Set-Cookie
response1 = requests.get(
    'https://example.com/login',
    cookies=jar,
    proxies={'https': 'http://proxy.example.com:8080'}
)

# تم حفظ ملفات تعريف الارتباط تلقائياً في jar
print(jar)

# الطلب الثاني — سيتم إرسال ملفات تعريف الارتباط تلقائياً
response2 = requests.get(
    'https://example.com/dashboard',
    cookies=jar,
    proxies={'https': 'http://proxy.example.com:8080'}
)

بدون jar، كان يتعين عليك تحليل Set-Cookie يدويًا وإضافتها إلى الطلب التالي — وهذا غير موثوق وثقيل.

حفظ ملفات تعريف الارتباط بين الطلبات

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

import requests
from http.cookiejar import LWPCookieJar

# ننشئ jar مع الحفظ في ملف
jar = LWPCookieJar('cookies.txt')

# نحمل ملفات تعريف الارتباط القديمة إن وجدت
try:
    jar.load(ignore_discard=True, ignore_expires=True)
except FileNotFoundError:
    pass

# نستخدم jar في الطلبات
response = requests.get(
    'https://example.com/login',
    cookies=jar,
    proxies={'https': 'http://proxy.example.com:8080'}
)

# نحفظ ملفات تعريف الارتباط المحدثة
jar.save(ignore_discard=True, ignore_expires=True)

تسمح الأعلام ignore_discard=True و ignore_expires=True بحفظ حتى ملفات تعريف الارتباط المؤقتة.

مشاكل ربط ملفات تعريف الارتباط بالنطاق

تحتوي ملفات تعريف الارتباط على سمة Domain التي تحدد النطاقات التي سيتم إرسالها إليها. تحدث المشاكل إذا:

  • أعاد الوكيل كتابة Host. إذا غيّر الوكيل رأس Host، قد يرفض cookie jar ملف تعريف الارتباط كمنتمٍ إلى نطاق آخر.
  • النطاقات الفرعية لا تتطابق. قد لا يتم إرسال ملف تعريف الارتباط لـ example.com إلى api.example.com.
  • المسار لا يتطابق. لن يتم إرسال ملف تعريف الارتباط لـ /api إلى /admin.

تحقق من سمات ملف تعريف الارتباط بهذه الطريقة:

import requests

response = requests.get(
    'https://example.com',
    proxies={'https': 'http://proxy.example.com:8080'}
)

# نطبع جميع ملفات تعريف الارتباط
for cookie in response.cookies:
    print(f"Name: {cookie.name}")
    print(f"Value: {cookie.value}")
    print(f"Domain: {cookie.domain}")
    print(f"Path: {cookie.path}")
    print(f"Secure: {cookie.secure}")
    print(f"HttpOnly: {cookie.has_nonstandard_attr('HttpOnly')}")
    print("---")

إذا كان Domain ضيقاً جداً، حاول تحديد ملفات تعريف الارتباط بشكل صريح بدلاً من الإدارة التلقائية:

headers = {
    'Cookie': 'session_id=abc123; user_token=xyz789'
}

response = requests.get(
    'https://example.com/api',
    headers=headers,
    proxies={'https': 'http://proxy.example.com:8080'}
)

أعلام Secure و HttpOnly

يعني العلم Secure أن ملف تعريف الارتباط يُرسل فقط عبر HTTPS. إذا كنت تستخدم وكيل HTTP للوصول إلى مورد HTTPS، تأكد من حماية الاتصال بالوكيل أو أن الوكيل يمرر HTTPS بشكل صحيح.

يحظر العلم HttpOnly الوصول إلى ملف تعريف الارتباط من JavaScript. هذا لا يؤثر على إرسال ملف تعريف الارتباط في الطلبات، لكن من المهم تذكر أنك لن تتمكن من قراءة ملفات تعريف الارتباط هذه من المتصفح.

عند العمل مع الوكلاء السكنية تأكد من:

  • يدعم الوكيل HTTPS (طريقة CONNECT)
  • الشهادات صحيحة (لا تستخدم verify=False في الإنتاج)
  • لا يتم إعادة كتابة الرؤوس بواسطة الوكيل

أمثلة عملية مع الأكواد

المثال 1: تسجيل الدخول مع حفظ الجلسة

import requests
from requests.cookies import RequestsCookieJar

jar = RequestsCookieJar()
proxy = 'http://proxy.example.com:8080'

# تسجيل الدخول
login_response = requests.post(
    'https://example.com/login',
    data={'username': 'user', 'password': 'pass'},
    cookies=jar,
    proxies={'https': proxy}
)

if login_response.status_code == 200:
    print("تم تسجيل الدخول بنجاح")
    
    # نستخدم الجلسة المحفوظة
    dashboard = requests.get(
        'https://example.com/dashboard',
        cookies=jar,
        proxies={'https': proxy}
    )
    print(dashboard.text)

المثال 2: معالجة طلبات متعددة

import requests
from http.cookiejar import LWPCookieJar
import time

jar = LWPCookieJar('session.txt')
try:
    jar.load(ignore_discard=True)
except:
    pass

proxy = 'http://proxy.example.com:8080'
urls = [
    'https://example.com/page1',
    'https://example.com/page2',
    'https://example.com/page3'
]

for url in urls:
    response = requests.get(
        url,
        cookies=jar,
        proxies={'https': proxy},
        timeout=10
    )
    print(f"{url}: {response.status_code}")
    jar.save(ignore_discard=True)
    time.sleep(1)  # لا تثقل الخادم

المثال 3: نقل ملفات تعريف الارتباط بشكل صريح عند وجود مشاكل

import requests

proxy = 'http://proxy.example.com:8080'

# إذا لم تعمل الإدارة التلقائية
cookies_dict = {
    'session_id': 'abc123def456',
    'user_pref': 'dark_mode'
}

headers = {
    'User-Agent': 'Mozilla/5.0...',
    'Cookie': '; '.join([f"{k}={v}" for k, v in cookies_dict.items()])
}

response = requests.get(
    'https://example.com/api/data',
    headers=headers,
    proxies={'https': proxy}
)

print(response.json())

تصحيح مشاكل ملفات تعريف الارتباط

إذا لم تعمل ملفات تعريف الارتباط، استخدم هذه الأدوات:

الأداة الغرض
requests.Session تدير ملفات تعريف الارتباط تلقائياً لجميع الطلبات في الجلسة
logging فعّل DEBUG لـ requests لرؤية جميع الرؤوس
Fiddler / Charles اعترض حركة المرور وشاهد رؤوس Set-Cookie و Cookie
curl -v اختبر نفس الشيء عبر الوكيل من سطر الأوامر

فعّل التسجيل للتصحيح:

import logging
import requests

logging.basicConfig(level=logging.DEBUG)

# الآن ستطبع جميع الطلبات الرؤوس وملفات تعريف الارتباط
response = requests.get(
    'https://example.com',
    proxies={'https': 'http://proxy.example.com:8080'}
)

تحقق من أن الوكيل لا يحظر ملفات تعريف الارتباط:

curl -v -x http://proxy.example.com:8080 https://example.com

# انظر إلى الرؤوس:
# Set-Cookie: ... (يجب أن تكون موجودة)
# Cookie: ... (يجب أن تُرسل في الطلب التالي)

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

الخلاصة

يتم حل مشاكل ملفات تعريف الارتباط عند العمل عبر الوكيل من خلال التكوين الصحيح:

  • استخدم cookie jar للإدارة التلقائية لملفات تعريف الارتباط
  • احفظ ملفات تعريف الارتباط بين الطلبات في ملف
  • تحقق من ربط النطاق وسمات المسار
  • تأكد من دعم HTTPS للوكيل
  • استخدم التصحيح لتحديد المشاكل

بالنسبة لمهام الأتمتة والتحليل، حيث تحتاج إلى عمل موثوق مع الجلسات عبر الوكيل، فإن الوكلاء السكنية مع دعم HTTPS وإدارة ملفات تعريف الارتباط مناسبة. ابدأ بـ cookie jar بسيط وانتقل إلى مخططات أكثر تعقيداً فقط إذا لزم الأمر.

```