http.cookies --- مدیریت وضعیت HTTP

کد منبع: Lib/http/cookies.py


ماژول http.cookies کلاس‌هایی را برای انتزاع مفهوم کوکی‌ها، یک سازوکار مدیریت وضعیت HTTP، تعریف می‌کند. این ماژول هم از کوکی‌های ساده‌ی فقط رشته‌ای پشتیبانی می‌کند و هم انتزاعی را برای داشتن هر نوع داده قابل سریال‌سازی به‌عنوان مقدار کوکی فراهم می‌کند.

این ماژول پیش‌تر قواعد تجزیه‌ی توصیف‌شده در مشخصات RFC 2109 و RFC 2068 را به‌طور سخت‌گیرانه اعمال می‌کرد. از آن زمان کشف شده است که MSIE 3.0x از قواعد نویسه‌ای مندرج در آن مشخصات پیروی نمی‌کرد؛ بسیاری از مرورگرها و سرورهای امروزی نیز قواعد تجزیه را در زمینه‌ی مدیریت کوکی آسان‌تر کرده‌اند. در نتیجه، این ماژول اکنون از قواعد تجزیه‌ای استفاده می‌کند که کمی کمتر از گذشته سخت‌گیرانه هستند.

مجموعه نویسه‌ها، string.ascii_letters، string.digits و !#$%&'*+-.^_`|~:، مجموعه‌ای از نویسه‌های معتبر مجاز توسط این ماژول در نام کوکی (به‌عنوان key) را نشان می‌دهند.

تغییر یافته در نسخه‌ی 3.3: نویسه‌ی ':' به‌عنوان نویسه‌ی معتبر نام کوکی مجاز شد.

توجه

در صورت مواجهه با یک کوکی نامعتبر، CookieError پرتاب می‌شود، بنابراین اگر داده‌های کوکی شما از یک مرورگر می‌آید، باید همیشه برای داده‌های نامعتبر آماده باشید و CookieError را هنگام تجزیه بگیرید.

exception http.cookies.CookieError

استثنای شکست به دلیل نامعتبر بودن از نظر RFC 2109: ویژگی‌های نادرست، سرآیند Set-Cookie نادرست، و غیره.

class http.cookies.BaseCookie([input])

این کلاس یک شیء دیکشنری‌مانند است که کلیدهای آن رشته و مقادیر آن نمونه‌های Morsel هستند. توجه داشته باشید که هنگام اختصاص یک مقدار به یک کلید، ابتدا مقدار به یک Morsel تبدیل می‌شود که شامل کلید و مقدار است.

اگر input داده شده باشد، به متد load() ارسال می‌شود.

class http.cookies.SimpleCookie([input])

این کلاس از BaseCookie مشتق می‌شود و value_decode() و value_encode() را بازنویسی می‌کند. SimpleCookie از رشته‌ها به‌عنوان مقادیر کوکی پشتیبانی می‌کند. هنگام تنظیم مقدار، SimpleCookie تابع توکار str() را فراخوانی می‌کند تا مقدار را به رشته تبدیل کند. مقادیر دریافت‌شده از HTTP به‌صورت رشته نگه‌داری می‌شوند.

همچنین ملاحظه نمائید

ماژول http.cookiejar

مدیریت کوکی‌های HTTP برای کلاینت‌های وب. ماژول‌های http.cookiejar و http.cookies به یکدیگر وابستگی ندارند.

RFC 2109 - سازوکار مدیریت وضعیت HTTP

این مشخصات مدیریت وضعیت است که توسط این ماژول پیاده‌سازی شده است.

اشیای Morsel

class http.cookies.Morsel

یک جفت کلید/مقدار را انتزاع می‌کند، که دارای برخی ویژگی‌های RFC 2109 است.

Morselها اشیای دیکشنری‌مانندی هستند که مجموعه‌ی کلیدهای آن‌ها ثابت است — ویژگی‌های معتبر RFC 2109، که عبارتند از:

expires
path
comment
domain
max-age
secure
version
httponly
samesite
partitioned

ویژگی httponly مشخص می‌کند که کوکی فقط در درخواست‌های HTTP منتقل می‌شود و از طریق JavaScript دسترس‌پذیر نیست. هدف از این امر، کاهش اثر برخی از انواع اسکریپت‌نویسی بین‌سایتی (cross-site scripting) است.

ویژگی samesite کنترل می‌کند که مرورگر چه زمانی کوکی را همراه با درخواست‌های بین‌سایتی ارسال می‌کند. این به کاهش حملات CSRF کمک می‌کند. مقادیر معتبر عبارتند از "Strict" (فقط همراه با درخواست‌های هم‌سایت ارسال می‌شود)، "Lax" (همراه با درخواست‌های هم‌سایت و پیمایش‌های سطح بالا ارسال می‌شود)، و "None" (همراه با درخواست‌های هم‌سایت و بین‌سایتی ارسال می‌شود). هنگام استفاده از "None"، ویژگی "secure" نیز باید تنظیم شود، همان‌طور که مرورگرهای مدرن الزامی می‌دانند.

ویژگی partitioned به عامل‌های کاربر نشان می‌دهد که این کوکی‌های بین‌سایتی باید فقط در همان زمینه سطح بالایی در دسترس باشند که کوکی نخستین بار در آن تنظیم شده است. برای آن‌که این موضوع توسط عامل کاربر پذیرفته شود، شما باید Secure را نیز تنظیم کنید.

علاوه بر این، توصیه می‌شود هنگام تنظیم کوکی‌های پارتیشن‌بندی‌شده (partitioned cookies) از پیشوند __Host استفاده کنید تا آن‌ها به نام میزبان مقید شوند، نه به دامنه‌ی ثبت‌پذیر. برای جزئیات و نمونه‌های کامل، CHIPS (Cookies Having Independent Partitioned State) را بخوانید.

کلیدها به بزرگی و کوچکی حروف حساس نیستند و مقدار پیش‌فرض آن‌ها '' است.

تغییر یافته در نسخه‌ی 3.5: __eq__() اکنون key و value را در نظر می‌گیرد.

تغییر یافته در نسخه‌ی 3.7: ویژگی‌های key، value و coded_value فقط‌خواندنی هستند. برای تنظیم آن‌ها از set() استفاده کنید.

تغییر یافته در نسخه‌ی 3.8: پشتیبانی از ویژگی samesite اضافه شد.

تغییر یافته در نسخه‌ی 3.14: پشتیبانی از ویژگی partitioned اضافه شد.

Morsel.value

مقدار کوکی.

Morsel.coded_value

مقدار کدگذاری‌شده‌ی کوکی — این همان مقداری است که باید ارسال شود.

Morsel.key

نام کوکی.

Morsel.set(key, value, coded_value)

ویژگی‌های key، value و coded_value را تنظیم کنید.

Morsel.isReservedKey(K)

اینکه آیا K عضوی از مجموعه‌ی کلیدهای یک Morsel است.

Morsel.output(attrs=None, header='Set-Cookie:')

یک نمایش رشته‌ای از Morsel برمی‌گرداند که برای ارسال به‌عنوان سرآیند HTTP مناسب است. به‌طور پیش‌فرض، همه ویژگی‌ها گنجانده می‌شوند، مگر اینکه attrs داده شده باشد، که در این صورت باید فهرستی از ویژگی‌های مورد استفاده باشد. header به‌طور پیش‌فرض "Set-Cookie:" است.

Morsel.js_output(attrs=None)

یک قطعه‌کد جاوااسکریپت قابل تعبیه برمی‌گرداند که اگر در مرورگری که از جاوااسکریپت پشتیبانی می‌کند اجرا شود، همان‌گونه عمل می‌کند که گویی سرآیند HTTP ارسال شده باشد.

معنای attrs همان معنای آن در output() است.

Morsel.OutputString(attrs=None)

یک رشته را برمی‌گرداند که نمایانگر Morsel است، بدون هیچ HTTP یا JavaScript پیرامونی.

معنای attrs همان معنای آن در output() است.

Morsel.update(values)

مقادیر دیکشنری Morsel را با مقادیر دیکشنری values به‌روزرسانی می‌کند. اگر یکی از کلیدهای دیکشنری values یک ویژگی معتبر RFC 2109 نباشد، خطایی پرتاب می‌کند.

تغییر یافته در نسخه‌ی 3.5: برای کلیدهای نامعتبر یک خطا پرتاب می‌شود.

Morsel.copy(value)

یک کپی سطحی از شیء Morsel برمی‌گرداند.

تغییر یافته در نسخه‌ی 3.5: یک شیء Morsel را به‌جای دیکشنری برمی‌گرداند.

Morsel.setdefault(key, value=None)

اگر کلید یک ویژگی معتبر RFC 2109 نباشد، خطایی پرتاب می‌کند؛ در غیر این صورت همانند dict.setdefault() رفتار می‌کند.

مثال

مثال زیر چگونگی استفاده از ماژول http.cookies را نشان می‌دهد.

>>> from http import cookies
>>> C = cookies.SimpleCookie()
>>> C["fig"] = "newton"
>>> C["sugar"] = "wafer"
>>> print(C) # generate HTTP headers
Set-Cookie: fig=newton
Set-Cookie: sugar=wafer
>>> print(C.output()) # same thing
Set-Cookie: fig=newton
Set-Cookie: sugar=wafer
>>> C = cookies.SimpleCookie()
>>> C["rocky"] = "road"
>>> C["rocky"]["path"] = "/cookie"
>>> print(C.output(header="Cookie:"))
Cookie: rocky=road; Path=/cookie
>>> print(C.output(attrs=[], header="Cookie:"))
Cookie: rocky=road
>>> C = cookies.SimpleCookie()
>>> C.load("chips=ahoy; vienna=finger") # load from a string (HTTP header)
>>> print(C)
Set-Cookie: chips=ahoy
Set-Cookie: vienna=finger
>>> C = cookies.SimpleCookie()
>>> C.load('keebler="E=everybody; L=\\"Loves\\"; fudge=;";')
>>> print(C)
Set-Cookie: keebler="E=everybody; L=\"Loves\"; fudge=;"
>>> C = cookies.SimpleCookie()
>>> C["oreo"] = "doublestuff"
>>> C["oreo"]["path"] = "/"
>>> print(C)
Set-Cookie: oreo=doublestuff; Path=/
>>> C = cookies.SimpleCookie()
>>> C["twix"] = "none for you"
>>> C["twix"].value
'none for you'
>>> C = cookies.SimpleCookie()
>>> C["number"] = 7 # equivalent to C["number"] = str(7)
>>> C["string"] = "seven"
>>> C["number"].value
'7'
>>> C["string"].value
'seven'
>>> print(C)
Set-Cookie: number=7
Set-Cookie: string=seven