Provides session management functionality, including lazy session starting, session segments, next-request-only (“flash”) values, and CSRF tools.
We are going to install
Add to your
Aura.Session already have
aura/session:session service which is an object of Aura\Session\Session . You can get inject the service to responder or view helper and make use of the Aura\Session\Session object.
In normal PHP, we keep session values in the
$_SESSION array. However, when different libraries and projects try to modify the same keys, the resulting conflicts can result in unexpected behavior. To resolve this, we use Segment objects. Each Segment addresses a named key within the
$_SESSION array for deconfliction purposes.
For example, if we get a Segment for
Vendor\Package\ClassName, that Segment will contain a reference to
$_SESSION['Vendor\Package\ClassName']. We can then
get() values on the Segment, and the values will reside in an array under that reference.
The benefit of a session segment is that we can deconflict the keys in the
$_SESSION superglobal by using class names (or some other unique name) for the segment names. With segments, different packages can use the
$_SESSION superglobal without stepping on each other’s toes.
To clear all the values on a Segment, use the
Merely instantiating the Session manager and getting a Segment from it does not call
session_start() occurs only in certain circumstances:
If we read from a Segment (e.g. with
get()) the Session looks to see if a session cookie has already been set. If so, it will call
session_start() to resume the previously-started session. If not, it knows there are no previously existing
$_SESSION values, so it will not call
If we write to a Segment (e.g. with
set()) the Session will always call
session_start(). This will resume a previous session if it exists, or start a new one if it does not.
This means we can create each Segment at will, and
session_start() will not be invoked until we actually interact with a Segment in a particular way. This helps to conserve the resources involved in starting a session.
Of course, we can force a session start or reactivation by calling the Session
start() method, but that defeats the purpose of lazy-loaded sessions.
These methods apply to all session data and flashes across all segments.
To save the session data and end its use during the current request, call the
commit() method on the Session manager:
commit()method is the equivalent of
session_write_close(). If you do not commit the session, its values will not be available when we continue the session later.
To clear all session data, but leave the session active during the current request, use the
clear() method on the Session manager.
To clear all flash values on a segment, use the
To clear the data and terminate the session for this and future requests, thereby destroying it completely, call the
destroy() will also delete the session cookie via
setcookie(). If we have an alternative means by which we delete cookies, we should pass a callable as the second argument to the SessionFactory method
newInstance(). The callable should take three parameters: the cookie name, path, and domain.
Any time a user has a change in privilege (that is, gaining or losing access rights within a system) be sure to regenerate the session ID:
regenerateId()method also regenerates the CSRF token value.
To defend against CSRF attacks, server-side logic should:
Place a token value unique to each authenticated user session in each form; and
Check that all incoming POST/PUT/DELETE (i.e., “unsafe”) requests contain that value.
If our application uses GET requests to modify resources (which incidentally is an improper use of GET), we should also check for CSRF on GET requests from authenticated users.
For this example, the form field name will be
__csrf_value. In each form
we want to protect against CSRF, we use the session CSRF token value for that
When processing the request, check to see if the incoming CSRF token is valid for the authenticated user:
For a CSRF token to be useful, its random value must be cryptographically
secure. Using things like
mt_rand() is insufficient. Aura.Session comes with
Randval class that implements a
RandvalInterface, and uses either the
openssl or the
mcrypt extension to generate a random value. If you do not
have one of these extensions installed, you will need your own random-value
implementation of the
RandvalInterface. We suggest a wrapper around
Segment values persist until the session is cleared or destroyed. However, sometimes it is useful to set a value that propagates only through the next request, and is then discarded. These are called “flash” values.
To set a flash value on a Segment, use the
Then, in subsequent requests, we can read the flash value using
get(), we can provide an alternative value if the flash key does not exist. For example,
getFlash('foo', 'not set')will return ‘not set’ if there is no ‘foo’ key available.
setFlash() makes the flash value available only in the next request, not the current one. To make the flash value available immediately as well as in the next request, use
getFlash() returns only the values that are available now from having been set in the previous request. To read a value that will be available in the next request, use
Sometimes we will want to keep the flash values in the current request for the next request. We can do so on a per-segment basis by calling the Segment
keepFlash() method, or we can keep all flashes for all segments by calling the Session
Similarly, we can clear flash values on a per-segment basis or a session-wide bases. Use the
clearFlash() method on the Segment to clear flashes just for that segment, or the same method on the Session to clear all flash values for all segments.