# Werkzeug

# Secure Cookie

This module implements a cookie that is not alterable from the client because it adds a checksum the server checks for. You can use it as session replacement if all you have is a user id or something to mark a logged in user.

Keep in mind that the data is still readable from the client as a normal cookie is. However you don’t have to store and flush the sessions you have at the server.

Example usage:

    >>> from werkzeug.contrib.securecookie import SecureCookie
    >>> x = SecureCookie({"foo": 42, "baz": (1, 2, 3)}, "deadbeef")

Dumping into a string so that one can store it in a cookie:

    >>> value = x.serialize()

Loading from that string again:

    >>> x = SecureCookie.unserialize(value, "deadbeef")
    >>> x["baz"]
    (1, 2, 3)

If someone modifies the cookie and the checksum is wrong the unserialize method will fail silently and return a new empty SecureCookie object.

Keep in mind that the values will be visible in the cookie so do not store data in a cookie you don’t want the user to see.

## Application Integration

If you are using the werkzeug request objects you could integrate the secure cookie into your application like this:

    from werkzeug import BaseRequest, cached_property
    from werkzeug.contrib.securecookie import SecureCookie

    # don't use this key but a different one; you could just use
    # os.unrandom(20) to get something random
    SECRET_KEY = '\xfa\xdd\xb8z\xae\xe0}4\x8b\xea'

    class Request(BaseRequest):

        @cached_property
        def client_session(self):
            data = self.cookies.get('session_data')
            if not data:
                return SecureCookie(secret_key=SECRET_KEY)
            return SecureCookie.unserialize(data, SECRET_KEY)

    def application(environ, start_response):
        request = Request(environ, start_response)

        # get a response object here
        response = ...

        if request.client_session.should_save:
            session_data = request.client_session.serialize()
            response.set_cookie('session_data', session_data,
                                httponly=True)
        return response(environ, start_response)

A less verbose integration can be achieved by using shorthand methods:

    class Request(BaseRequest):

        @cached_property
        def client_session(self):
            return SecureCookie.load_cookie(self, secret_key=COOKIE_SECRET)

    def application(environ, start_response):
        request = Request(environ, start_response)

        # get a response object here
        response = ...

        request.client_session.save_cookie(response)
        return response(environ, start_response)

## Reference

class `werkzeug.contrib.securecookie.``SecureCookie`(data=None, secret_key=None, new=True)

  Represents a secure cookie. You can subclass this class and provide an alternative mac method. The import thing is that the mac method is a function with a similar interface to the hashlib. Required methods are update() and digest().

  Example usage:

      >>> x = SecureCookie({"foo": 42, "baz": (1, 2, 3)}, "deadbeef")
      >>> x["foo"]
      42
      >>> x["baz"]
      (1, 2, 3)
      >>> x["blafasel"] = 23
      >>> x.should_save
      True

  Parameters:

  - data – the initial data. Either a dict, list of tuples or None.
  - secret_key – the secret key. If not set None or not specified it has to be set before `serialize()` is called.
  - new – The initial value of the new flag.

  `new`
    True if the cookie was newly created, otherwise False
  `modified`

    Whenever an item on the cookie is set, this attribute is set to True. However this does not track modifications inside mutable objects in the cookie:

        >>> c = SecureCookie()
        >>> c["foo"] = [1, 2, 3]
        >>> c.modified
        True
        >>> c.modified = False
        >>> c["foo"].append(4)
        >>> c.modified
        False

    In that situation it has to be set to modified by hand so that `should_save` can pick it up.

  `hash_method`
    The hash method to use. This has to be a module with a new function or a function that creates a hashlib object. Such as hashlib.md5 Subclasses can override this attribute. The default hash is sha1.
  classmethod `load_cookie`(request, key='session', secret_key=None)

    Loads a `SecureCookie` from a cookie in request. If the cookie is not set, a new `SecureCookie` instanced is returned.

    Parameters:

    - request – a request object that has a cookies attribute which is a dict of all cookie values.
    - key – the name of the cookie.
    - secret_key – the secret key used to unquote the cookie. Always provide the value even though it has no default!

  classmethod `quote`(value)

    Quote the value for the cookie. This can be any object supported by `serialization_method`.

    Parameters:

    - value – the value to quote.

  `quote_base64`
    if the contents should be base64 quoted. This can be disabled if the serialization process returns cookie safe strings only.
  `save_cookie`(response, key='session', expires=None, session_expires=None, max_age=None, path='/', domain=None, secure=None, httponly=False, force=False)

    Saves the SecureCookie in a cookie on response object. All parameters that are not described here are forwarded directly to `set_cookie()`.

    Parameters:

    - response – a response object that has a `set_cookie()` method.
    - key – the name of the cookie.
    - session_expires – the expiration date of the secure cookie stored information. If this is not provided the cookie expires date is used instead.

  `serialization_method`
    the module used for serialization. Unless overriden by subclasses the standard pickle module is used.
  `serialize`(expires=None)

    Serialize the secure cookie into a string.

    If expires is provided, the session will be automatically invalidated after expiration when you unseralize it. This provides better protection against session cookie theft.

    Parameters:

    - expires – an optional expiration date for the cookie (a `datetime.datetime` object)

  `should_save`
    True if the session should be saved. By default this is only true for `modified` cookies, not `new`.
  classmethod `unquote`(value)

    Unquote the value for the cookie. If unquoting does not work a `UnquoteError` is raised.

    Parameters:

    - value – the value to unquote.

  classmethod `unserialize`(string, secret_key)

    Load the secure cookie from a serialized string.

    Parameters:

    - string – the cookie value to unserialize.
    - secret_key – the secret key used to serialize the cookie.

    Returns: | a new `SecureCookie`.

exception `werkzeug.contrib.securecookie.``UnquoteError`
  Internal exception used to signal failures on quoting.