summaryrefslogtreecommitdiff
path: root/docs/narr/sessions.rst
diff options
context:
space:
mode:
authorCasey Duncan <casey.duncan@gmail.com>2011-01-05 23:21:12 -0700
committerCasey Duncan <casey.duncan@gmail.com>2011-01-05 23:21:12 -0700
commitb0b9f70b16aeb36b8588efde13b7b2475a46278b (patch)
treed15325aabec803f802839d636f48ed6162334324 /docs/narr/sessions.rst
parent4614826b25f692ff431a110d371242a470ef0681 (diff)
downloadpyramid-b0b9f70b16aeb36b8588efde13b7b2475a46278b.tar.gz
pyramid-b0b9f70b16aeb36b8588efde13b7b2475a46278b.tar.bz2
pyramid-b0b9f70b16aeb36b8588efde13b7b2475a46278b.zip
combine flash and csrf into sessions chapt
Diffstat (limited to 'docs/narr/sessions.rst')
-rw-r--r--docs/narr/sessions.rst183
1 files changed, 181 insertions, 2 deletions
diff --git a/docs/narr/sessions.rst b/docs/narr/sessions.rst
index cb3545a06..a4e30520f 100644
--- a/docs/narr/sessions.rst
+++ b/docs/narr/sessions.rst
@@ -3,8 +3,8 @@
.. _sessions_chapter:
-Session Objects
-===============
+Sessions
+========
A :term:`session` is a namespace which is valid for some period of
continual activity that can be used to represent a user's interaction
@@ -162,3 +162,182 @@ both types are available in
:class:`pyramid.interfaces.ISession`. You might use the cookie
implementation in the :mod:`pyramid.session` module as inspiration.
+.. index::
+ single: flash messages
+
+Flash Messages
+--------------
+
+"Flash messages" are simply a queue of message strings stored in the
+:term:`session`. To use flash messaging, you must enable a :term:`session
+factory` as described in :ref:`using_the_default_session_factory` or
+:ref:`using_alternate_session_factories`.
+
+Flash messaging has two main uses: to display a status message only once to
+the user after performing an internal redirect, and to allow generic code to
+log messages for single-time display without having direct access to an HTML
+template. The user interface consists of a number of methods of the
+:term:`session` object.
+
+Using the ``session.flash`` Method
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To add a message to a flash message queue, use a session object's ``flash``
+method:
+
+.. code-block:: python
+ :linenos:
+
+ request.session.flash('mymessage')
+
+The ``.flash`` method appends a message to a flash queue, creating the queue
+if necessary.
+
+``.flash`` accepts three arguments:
+
+.. method:: flash(message, queue='', allow_duplicate=True)
+
+The ``message`` argument is required. It represents a message you wish to
+later display to a user. It is usually a string but the ``message`` you
+provide is not modified in any way.
+
+The ``queue`` argument allows you to choose a queue to which to append the
+message you provide. This can be used to push different kinds of messages
+into flash storage for later display in different places on a page. You can
+pass any name for your queue, but it must be a string. The default value is
+the empty string, which chooses the default queue. Each queue is independent,
+and can be popped by ``pop_flash`` or examined via ``peek_flash`` separately.
+``queue`` defaults to the empty string. The empty string represents the
+default flash message queue.
+
+.. code-block:: python
+
+ request.session.flash(msg, 'myappsqueue')
+
+The ``allow_duplicate`` argument defaults to ``True``. If this is
+``False``, if you attempt to add a message to a queue which is already
+present in the queue, it will not be added.
+
+Using the ``session.pop_flash`` Method
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once one or more messages have been added to a flash queue by the
+``session.flash`` API, the ``session.pop_flash`` API can be used to pop that
+queue and return it for use.
+
+To pop a particular queue of messages from the flash object, use the session
+object's ``pop_flash`` method.
+
+.. method:: pop_flash(queue='')
+
+.. code-block:: python
+ :linenos:
+
+ >>> request.session.flash('info message')
+ >>> request.session.pop_flash()
+ ['info message']
+
+Calling ``session.pop_flash()`` again like above without a corresponding call
+to ``session.flash`` will return an empty list, because the queue has already
+been popped.
+
+.. code-block:: python
+ :linenos:
+
+ >>> request.session.flash('info message')
+ >>> request.session.pop_flash()
+ ['info message']
+ >>> request.session.pop_flash()
+ []
+
+The object returned from ``pop_flash`` is a list.
+
+Using the ``session.peek_flash`` Method
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Once one or more messages has been added to a flash queue by the
+``session.flash`` API, the ``session.peek_flash`` API can be used to "peek"
+at that queue. Unlike ``session.pop_flash``, the queue is not popped from
+flash storage.
+
+.. method:: peek_flash(queue='')
+
+.. code-block:: python
+ :linenos:
+
+ >>> request.session.flash('info message')
+ >>> request.session.peek_flash()
+ ['info message']
+ >>> request.session.peek_flash()
+ ['info message']
+ >>> request.session.pop_flash()
+ ['info message']
+ >>> request.session.peek_flash()
+ []
+
+.. index::
+ single: preventing cross-site request forgery attacks
+ single: cross-site request forgery attacks, prevention
+
+Preventing Cross-Site Request Forgery Attacks
+---------------------------------------------
+
+`Cross-site request forgery
+<http://en.wikipedia.org/wiki/Cross-site_request_forgery>`_ attacks are a
+phenomenon whereby a user with an identity on your website might click on a
+URL or button on another website which unwittingly redirects the user to your
+application to perform some command that requires elevated privileges.
+
+You can avoid most of these attacks by making sure that the correct *CSRF
+token* has been set in an :app:`Pyramid` session object before performing any
+actions in code which requires elevated privileges and is invoked via a form
+post. To use CSRF token support, you must enable a :term:`session factory`
+as described in :ref:`using_the_default_session_factory` or
+:ref:`using_alternate_session_factories`.
+
+Using the ``session.new_csrf_token`` Method
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To add a CSRF token to the session, use the ``session.new_csrf_token`` method.
+
+.. code-block:: python
+ :linenos:
+
+ token = request.session.new_csrf_token()
+
+The ``.new_csrf_token`` method accepts no arguments. It returns a *token*
+string, which will be opaque and randomized. This token will also be set
+into the session, awaiting pickup by the ``session.get_csrf_token`` method.
+You can subsequently use the returned token as the value of a hidden field in
+a form that posts to a method that requires elevated privileges. The handler
+for the form post should use ``session.get_csrf_token`` (explained below) to
+obtain the current CSRF token related to the user from the session, and
+compare it to the value of the hidden form field.
+
+Using the ``session.get_csrf_token`` Method
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To get the current CSRF token from the session, use the
+``session.get_csrf_token`` method.
+
+.. code-block:: python
+ :linenos:
+
+ token = request.session.get_csrf_token()
+
+The ``get_csrf_token`` method accepts no arguments. It returns the "current"
+*token* string (as per the last call to ``session.new_csrf_token``). You can
+then use it to compare against the token provided within form post hidden
+value data. For example, if your form rendering included the CSRF token
+obtained via ``session.new_csrf_token`` as a hidden input field named
+``csrf_token``:
+
+.. code-block:: python
+ :linenos:
+
+ token = request.session.get_csrf_token()
+ if token != request.POST['csrf_token']:
+ raise ValueError('CSRF token did not match')
+
+
+