~sidnei/zope3/reduce-deps

« back to all changes in this revision

Viewing changes to src/zope/app/session/api.txt

  • Committer: Sidnei da Silva
  • Date: 2010-07-05 21:07:01 UTC
  • Revision ID: sidnei.da.silva@canonical.com-20100705210701-zmqhqrbzad1mhzsl
- Reduce deps

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
Zope3 Session Implementation
2
 
============================
3
 
 
4
 
Overview
5
 
--------
6
 
 
7
 
.. CAUTION::
8
 
    Session data is maintained on the server. This gives a security
9
 
    advantage in that we can assume that a client has not tampered with
10
 
    the data.  However, this can have major implications for scalability
11
 
    as modifying session data too frequently can put a significant load
12
 
    on servers and in extreme situations render your site unusable.
13
 
    Developers should keep this in mind when writing code or risk
14
 
    problems when their application is run in a production environment.
15
 
 
16
 
    Applications requiring write-intensive session implementations (such
17
 
    as page counters) should consider using cookies or specialized
18
 
    session implementations.
19
 
 
20
 
Sessions allow us to fake state over a stateless protocol - HTTP.
21
 
We do this by having a unique identifier stored across multiple
22
 
HTTP requests, be it a cookie or some id mangled into the URL.
23
 
 
24
 
 
25
 
The `IClientIdManager` Utility provides this unique id. It is
26
 
responsible for propagating this id so that future requests from
27
 
the client get the same id (eg. by setting an HTTP cookie). This
28
 
utility is used when we adapt the request to the unique client id:
29
 
 
30
 
    >>> client_id = IClientId(request)
31
 
 
32
 
The `ISession` adapter gives us a mapping that can be used to store
33
 
and retrieve session data. A unique key (the package id) is used
34
 
to avoid namespace clashes:
35
 
 
36
 
    >>> pkg_id = 'products.foo'
37
 
    >>> session = ISession(request)[pkg_id]
38
 
    >>> session['color'] = 'red'
39
 
 
40
 
    >>> session2 = ISession(request)['products.bar']
41
 
    >>> session2['color'] = 'blue'
42
 
 
43
 
    >>> session['color']
44
 
    'red'
45
 
    >>> session2['color']
46
 
    'blue'
47
 
 
48
 
 
49
 
Data Storage
50
 
------------
51
 
 
52
 
The actual data is stored in an `ISessionDataContainer` utility.
53
 
`ISession` chooses which `ISessionDataContainer` should be used by
54
 
looking up as a named utility using the package id. This allows
55
 
the site administrator to configure where the session data is actually
56
 
stored by adding a registration for desired `ISessionDataContainer`
57
 
with the correct name.
58
 
 
59
 
    >>> from zope.component import getUtility
60
 
    >>> sdc = getUtility(ISessionDataContainer, pkg_id)
61
 
    >>> sdc[client_id][pkg_id] is session
62
 
    True
63
 
    >>> sdc[client_id][pkg_id]['color']
64
 
    'red'
65
 
 
66
 
If no `ISessionDataContainer` utility can be located by name using the
67
 
package id, then the unnamed `ISessionDataContainer` utility is used as
68
 
a fallback. An unnamed `ISessionDataContainer` is automatically created
69
 
for you, which may replaced with a different implementation if desired.
70
 
 
71
 
    >>> ISession(request)['unknown'] \
72
 
    ...     is getUtility(ISessionDataContainer)[client_id]['unknown']
73
 
    True
74
 
 
75
 
The `ISessionDataContainer` contains `ISessionData` objects, and
76
 
`ISessionData` objects in turn contain `ISessionPkgData` objects. You
77
 
should never need to know this unless you are writing administrative
78
 
views for the session machinery.
79
 
 
80
 
    >>> ISessionData.providedBy(sdc[client_id])
81
 
    True
82
 
    >>> ISessionPkgData.providedBy(sdc[client_id][pkg_id])
83
 
    True
84
 
 
85
 
The `ISessionDataContainer` is responsible for expiring session data.
86
 
The expiry time can be configured by settings its `timeout` attribute.
87
 
 
88
 
    >>> sdc.timeout = 1200 # 1200 seconds or 20 minutes
89
 
 
90
 
 
91
 
Restrictions
92
 
------------
93
 
 
94
 
Data stored in the session must be persistent or picklable.
95
 
 
96
 
    >>> session['oops'] = open(__file__)
97
 
    >>> import transaction
98
 
    >>> transaction.commit()
99
 
    Traceback (most recent call last):
100
 
        [...]
101
 
    TypeError: can't pickle file objects
102
 
 
103
 
    Clean up:
104
 
    >>> transaction.abort()
105
 
 
106
 
 
107
 
Page Templates
108
 
--------------
109
 
 
110
 
    Session data may be accessed in page template documents using
111
 
    TALES::
112
 
 
113
 
        <span tal:content="request/session:products.foo/color | default">
114
 
            green
115
 
        </span>
116
 
 
117
 
    or::
118
 
 
119
 
        <div tal:define="session request/session:products.foo">
120
 
            <script type="text/server-python">
121
 
                try:
122
 
                    session['count'] += 1
123
 
                except KeyError:
124
 
                    session['count'] = 1
125
 
            </script>
126
 
 
127
 
            <span tal:content="session/count" />
128
 
        </div>
129