Cookie – HTTP Cookies¶
|Purpose:||The Cookie module defines classes for parsing and creating HTTP cookie headers.|
|Available In:||2.1 and later|
Cookies have been a part of the HTTP protocol for a long time. All of the modern web development frameworks provide easy access to cookies so a programmer almost never has to worry about how to format them or make sure the headers are sent properly. It can be instructive to understand how cookies work, though, and the options they support.
The Cookie module implements a parser for cookies that is mostly RFC 2109 compliant. It is a little less strict than the standard because MSIE 3.0x does not support the entire standard.
It is also possible to control the other aspects of a cookie, such as the expiration, path, and domain. In fact, all of the RFC attributes for cookies can be managed through the Morsel object representing the cookie value.
import Cookie import datetime def show_cookie(c): print c for key, morsel in c.iteritems(): print print 'key =', morsel.key print ' value =', morsel.value print ' coded_value =', morsel.coded_value for name in morsel.keys(): if morsel[name]: print ' %s = %s' % (name, morsel[name]) c = Cookie.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'] = 'Notice that this cookie value has escaped quotes' # 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' expires = datetime.datetime(2009, 2, 14, 18, 30, 14) + datetime.timedelta(hours=1) c['expires_at_time']['expires'] = expires.strftime('%a, %d %b %Y %H:%M:%S') # Wdy, DD-Mon-YY HH:MM:SS GMT show_cookie(c)
The above example includes two different methods for setting stored cookies that expire. You can set max-age to a number of seconds, or expires to a date and time when the cookie should be discarded.
$ python Cookie_Morsel.py Set-Cookie: encoded_value_cookie="\"cookie_value\""; Comment=Notice that this cookie value has escaped quotes 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 = restricted_cookie value = cookie_value coded_value = cookie_value domain = PyMOTW secure = True path = /sub/path key = with_max_age value = expires in 5 minutes coded_value = "expires in 5 minutes" max-age = 300 key = encoded_value_cookie value = "cookie_value" coded_value = "\"cookie_value\"" comment = Notice that this cookie value has escaped quotes key = expires_at_time value = cookie_value coded_value = cookie_value expires = Sat, 14 Feb 2009 19:30:14
Both the Cookie and Morsel objects act like dictionaries. The Morsel responds to a fixed set of keys:
The keys for the Cookie instance are the names of the individual cookies being stored. That information is also available from the key attribute of the Morsel.
The cookie header may require values to be encoded so they can be parsed properly.
import Cookie c = Cookie.SimpleCookie() c['integer'] = 5 c['string_with_quotes'] = 'He said, "Hello, World!"' for name in ['integer', 'string_with_quotes']: print c[name].key print ' %s' % c[name] print ' value=%s' % c[name].value, type(c[name].value) print ' coded_value=%s' % c[name].coded_value print
The Morsel.value is always the decoded value of the cookie, while Morsel.coded_value is always the representation to be used for transmitting the value to the client. Both values are always strings. Values saved to a cookie that are not strings are converted automatically.
$ python Cookie_coded_value.py integer Set-Cookie: integer=5 value=5 <type 'str'> coded_value=5 string_with_quotes Set-Cookie: string_with_quotes="He said\054 \"Hello\054 World!\"" value=He said, "Hello, World!" <type 'str'> coded_value="He said\054 \"Hello\054 World!\""
Alternative Output Formats¶
import Cookie c = Cookie.SimpleCookie() c['mycookie'] = 'cookie_value' c['another_cookie'] = 'second value' print c.js_output()
All of these examples have used SimpleCookie. The Cookie module also provides 2 other classes, SerialCookie and SmartCookie. SerialCookie can handle any values that can be pickled. SmartCookie figures out whether a value needs to be unpickled or if it is a simple value. Since both of these classes use pickles, they are potential security holes in your application and you should not use them. It is safer to store state on the server, and give the client a session key instead.