http.cookies — Cookies HTTP

Propósito:Define las clases para analizar y crear encabezados de cookie HTTP.

El módulo http.cookies implementa un analizador para cookies que es en su mayoría compatible al RFC 2109. La implementación es un poco menos estricta que el estándar porque MSIE 3.0x no admite la totalidad estándar.

Morsels

También es posible controlar otros aspectos de una cookie, como la caducidad, la ruta y el dominio. De hecho, todos los atributos RFC las cookies se pueden gestionar a través del objeto Morsel que representa el valor de la cookie.

http_cookies_Morsel.py
from http import cookies
import datetime


def show_cookie(c):
    print(c)
    for key, morsel in c.items():
        print()
        print('key =', morsel.key)
        print('  value =', morsel.value)
        print('  coded_value =', morsel.coded_value)
        for name in morsel.keys():
            if morsel[name]:
                print('  {} = {}'.format(name, morsel[name]))


c = cookies.SimpleCookie()

# A cookie with a value that has to be encoded
# to fit into the header
c['encoded_value_cookie'] = '"cookie,value;"'
c['encoded_value_cookie']['comment'] = 'Has escaped punctuation'

# A cookie that only applies to part of a site
c['restricted_cookie'] = 'cookie_value'
c['restricted_cookie']['path'] = '/sub/path'
c['restricted_cookie']['domain'] = 'PyMOTW'
c['restricted_cookie']['secure'] = True

# A cookie that expires in 5 minutes
c['with_max_age'] = 'expires in 5 minutes'
c['with_max_age']['max-age'] = 300  # seconds

# A cookie that expires at a specific time
c['expires_at_time'] = 'cookie_value'
time_to_live = datetime.timedelta(hours=1)
expires = (datetime.datetime(2009, 2, 14, 18, 30, 14) +
           time_to_live)

# Date format: Wdy, DD-Mon-YY HH:MM:SS GMT
expires_at_time = expires.strftime('%a, %d %b %Y %H:%M:%S')
c['expires_at_time']['expires'] = expires_at_time

show_cookie(c)

Este ejemplo incluye dos métodos diferentes para configurar cookies almacenadas que caducan. Uno establece el max-age en varios segundos, el otro define expires en una fecha y hora en que la cookie debería ser descartada.

$ python3 http_cookies_Morsel.py

Set-Cookie: encoded_value_cookie="\"cookie\054value\073\"";
Comment=Has escaped punctuation
Set-Cookie: expires_at_time=cookie_value; expires=Sat, 14 Feb
2009 19:30:14
Set-Cookie: restricted_cookie=cookie_value; Domain=PyMOTW;
Path=/sub/path; Secure
Set-Cookie: with_max_age="expires in 5 minutes"; Max-Age=300

key = encoded_value_cookie
  value = "cookie,value;"
  coded_value = "\"cookie\054value\073\""
  comment = Has escaped punctuation

key = restricted_cookie
  value = cookie_value
  coded_value = cookie_value
  path = /sub/path
  domain = PyMOTW
  secure = True

key = with_max_age
  value = expires in 5 minutes
  coded_value = "expires in 5 minutes"
  max-age = 300

key = expires_at_time
  value = cookie_value
  coded_value = cookie_value
  expires = Sat, 14 Feb 2009 19:30:14

Tanto los objetos Cookie como los Morsel actúan como diccionarios. Un Morsel responde a un conjunto fijo de llaves:

  • expires
  • path
  • comment
  • domain
  • max-age
  • secure
  • version

Las llaves para una instancia de Cookie son los nombres de cookies individuales que se almacenan. Esa información también está disponible de los atributos llave del Morsel.

Valores codificados

El encabezado de la cookie necesita que los valores estén codificados para que puedan ser analizados correctamente.

http_cookies_coded_value.py
from http import cookies


c = cookies.SimpleCookie()
c['integer'] = 5
c['with_quotes'] = 'He said, "Hello, World!"'

for name in ['integer', 'with_quotes']:
    print(c[name].key)
    print('  {}'.format(c[name]))
    print('  value={!r}'.format(c[name].value))
    print('  coded_value={!r}'.format(c[name].coded_value))
    print()

Morsel.value es siempre el valor decodificado de la cookie, mientras que Morsel.coded_value es siempre la representación que se usa para transmitir el valor al cliente. Ambos valores son siempre cadenas de texto. Los valores guardados en una cookie que no son cadenas se convierten automáticamente.

$ python3 http_cookies_coded_value.py

integer
  Set-Cookie: integer=5
  value='5'
  coded_value='5'

with_quotes
  Set-Cookie: with_quotes="He said\054 \"Hello\054 World!\""
  value='He said, "Hello, World!"'
  coded_value='"He said\\054 \\"Hello\\054 World!\\""'

Recibir y analizar encabezados de cookies

Una vez que el cliente reciba los encabezados Set-Cookie, devolverá esas cookies al servidor en las solicitudes posteriores utilizando un encabezado Cookie. Una cadena de encabezado Cookie entrante puede contener varios valores de cookie, separados por punto y coma (;).

Cookie: integer=5; with_quotes="He said, \"Hello, World!\""

Dependiendo del servidor web y el marco, las cookies están disponible directamente desde los encabezados o la variable de entorno HTTP_COOKIE.

http_cookies_parse.py
from http import cookies


HTTP_COOKIE = '; '.join([
    r'integer=5',
    r'with_quotes="He said, \"Hello, World!\""',
])

print('From constructor:')
c = cookies.SimpleCookie(HTTP_COOKIE)
print(c)

print()
print('From load():')
c = cookies.SimpleCookie()
c.load(HTTP_COOKIE)
print(c)

Para decodificarlos, pasa la cadena sin el prefijo de encabezado a SimpleCookie al crear una instancia, o usa el método load().

$ python3 http_cookies_parse.py

From constructor:
Set-Cookie: integer=5
Set-Cookie: with_quotes="He said, \"Hello, World!\""

From load():
Set-Cookie: integer=5
Set-Cookie: with_quotes="He said, \"Hello, World!\""

Formatos alternativos de salida

Además de usar el encabezado Set-Cookie, los servidores pueden entregar JavaScript que agrega cookies a un cliente. SimpleCookie y Morsel proporcionan una salida de JavaScript a través del método js_output().

http_cookies_js_output.py
from http import cookies
import textwrap


c = cookies.SimpleCookie()
c['mycookie'] = 'cookie_value'
c['another_cookie'] = 'second value'
js_text = c.js_output()
print(textwrap.dedent(js_text).lstrip())

El resultado es una etiqueta script completa con sentencias para establecer las cookies.

$ python3 http_cookies_js_output.py

<script type="text/javascript">
<!-- begin hiding
document.cookie = "another_cookie=\"second value\"";
// end hiding -->
</script>

<script type="text/javascript">
<!-- begin hiding
document.cookie = "mycookie=cookie_value";
// end hiding -->
</script>

Ver también