1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280
|
NAME
CGI::Application::Plugin::Session - Add CGI::Session support to
CGI::Application
SYNOPSIS
use CGI::Application::Plugin::Session;
my $language = $self->session->param('language');
DESCRIPTION
CGI::Application::Plugin::Session seamlessly adds session support to
your CGI::Application modules by providing a CGI::Session object that
is accessible from anywhere in the application.
Lazy loading is used to prevent expensive file system or database calls
from being made if the session is not needed during this request. In
other words, the Session object is not created until it is actually
needed. Also, the Session object will act as a singleton by always
returning the same Session object for the duration of the request.
This module aims to be as simple and non obtrusive as possible. By not
requiring any changes to the inheritance tree of your modules, it can
be easily added to existing applications. Think of it as a plugin
module that adds a couple of new methods directly into the
CGI::Application namespace simply by loading the module.
METHODS
session
This method will return the current CGI::Session object. The
CGI::Session object is created on the first call to this method, and
any subsequent calls will return the same object. This effectively
creates a singleton session object for the duration of the request.
CGI::Session will look for a cookie or param containing the session ID,
and create a new session if none is found. If session_config has not
been called before the first call to session, then it will choose some
sane defaults to create the session object.
# retrieve the session object
my $session = $self->session;
- or -
# use the session object directly
my $language = $self->session->param('language');
session_config
This method can be used to customize the functionality of the
CGI::Application::Plugin::Session module. Calling this method does not
mean that a new session object will be immediately created. The session
object will not be created until the first call to $self->session. This
'lazy loading' can prevent expensive file system or database calls from
being made if the session is not needed during this request.
The recommended place to call session_config is in the cgiapp_init
stage of CGI::Application. If this method is called after the session
object has already been accessed, then it will die with an error
message.
If this method is not called at all then a reasonable set of defaults
will be used (the exact default values are defined below).
The following parameters are accepted:
CGI_SESSION_OPTIONS
This allows you to customize how the CGI::Session object is created
by providing a list of options that will be passed to the
CGI::Session constructor. Please see the documentation for
CGI::Session for the exact syntax of the parameters.
DEFAULT_EXPIRY
CGI::Session Allows you to set an expiry time for the session. You
can set the DEFAULT_EXPIRY option to have a default expiry time set
for all newly created sessions. It takes the same format as the
$session->expiry method of CGI::Session takes. Note that it is only
set for new session, not when a session is reloaded from the store.
COOKIE_PARAMS
This allows you to customize the options that are used when creating
the session cookie. For example you could provide an expiry time for
the cookie by passing -expiry => '+24h'. The -name and -value
parameters for the cookie will be added automatically unless you
specifically override them by providing -name and/or -value
parameters. See the CGI::Cookie docs for the exact syntax of the
parameters.
NOTE: You can do the following to get both the cookie name and the
internal name of the CGI::Session object to be changed:
$self->session_config(
CGI_SESSION_OPTIONS => [
$driver,
$self->query,
\%driver_options,
{ name => 'new_cookie_name' } # change cookie and session name
]
);
Also, if '-name' parameter and 'name' of session don't match a
warning will be emitted.
SEND_COOKIE
If set to a true value, the module will automatically add a cookie
header to the outgoing headers if a new session is created (Since the
session module is lazy loaded, this will only happen if you make a
call to $self->session at some point to create the session object).
This option defaults to true. If it is set to false, then no session
cookies will be sent, which may be useful if you prefer URL based
sessions (it is up to you to pass the session ID in this case).
The following example shows what options are set by default (ie this is
what you would get if you do not call session_config).
$self->session_config(
CGI_SESSION_OPTIONS => [ "driver:File", $self->query, {Directory=>'/tmp'} ],
COOKIE_PARAMS => {
-path => '/',
},
SEND_COOKIE => 1,
);
Here is a more customized example that uses the PostgreSQL driver and
sets an expiry and domain on the cookie.
$self->session_config(
CGI_SESSION_OPTIONS => [ "driver:PostgreSQL;serializer:Storable", $self->query, {Handle=>$dbh} ],
COOKIE_PARAMS => {
-domain => 'mydomain.com',
-expires => '+24h',
-path => '/',
-secure => 1,
},
);
session_cookie
This method will add a cookie to the outgoing headers containing the
session ID that was assigned by the CGI::Session module.
This method is called automatically the first time $self->session is
accessed if SEND_COOKIE was set true, which is the default, so it will
most likely never need to be called manually.
NOTE that if you do choose to call it manually that a session object
will automatically be created if it doesn't already exist. This removes
the lazy loading benefits of the plugin where a session is only
created/loaded when it is required.
It could be useful if you want to force the cookie header to be sent
out even if the session is not used on this request, or if you want to
manage the headers yourself by turning SEND_COOKIE to false.
# Force the cookie header to be sent including some
# custom cookie parameters
$self->session_cookie(-secure => 1, -expires => '+1w');
session_loaded
This method will let you know if the session object has been loaded
yet. In other words, it lets you know if $self->session has been
called.
sub cgiapp_postrun {
my $self = shift;
$self->session->flush if $self->session_loaded;;
}
session_recreate
This method will delete the existing session, and create a brand new
one for you with a new session ID. It copies over all existing
parameters into the new session.
This can be useful to protect against some login attacks when storing
authentication tokens in the session. Very briefly, an attacker loads a
page on your site and creates a session, then tries to trick a victim
into loading this page with the same session ID (possibly by embedding
it in a URL). Then if the victim follows the link and subsequently logs
into their account, the attacker will have a valid session ID where the
session is now logged in, and hence the attacker has access to the
victims account.
sub mylogin {
my $self = shift;
if ($newly_authenticated) {
$self->session_recreate;
}
}
session_delete
This method will perform a more comprehensive clean-up of the session,
calling both the CGI::Session delete() method, but also deleting the
cookie from the client, if you are using cookies.
sub logout {
my $self = shift;
$self->session_delete;
# what now? redirect user back to the homepage?
}
EXAMPLE
In a CGI::Application module:
# configure the session once during the init stage
sub cgiapp_init {
my $self = shift;
# Configure the session
$self->session_config(
CGI_SESSION_OPTIONS => [ "driver:PostgreSQL;serializer:Storable", $self->query, {Handle=>$self->dbh} ],
DEFAULT_EXPIRY => '+1w',
COOKIE_PARAMS => {
-expires => '+24h',
-path => '/',
},
SEND_COOKIE => 1,
);
}
sub cgiapp_prerun {
my $self = shift;
# Redirect to login, if necessary
unless ( $self->session->param('~logged-in') ) {
$self->prerun_mode('login');
}
}
sub my_runmode {
my $self = shift;
# Load the template
my $template = $self->load_tmpl('my_runmode.tmpl');
# Add all the session parameters to the template
$template->param($self->session->param_hashref());
# return the template output
return $template->output;
}
TODO
* I am considering adding support for other session modules in the
future, like Apache::Session and possibly others if there is a
demand.
* Possibly add some tests to make sure cookies are accepted by the
client.
* Allow a callback to be executed right after a session has been
created
SEE ALSO
CGI::Application, CGI::Session, perl(1)
AUTHOR
Cees Hek <ceeshek@gmail.com>
LICENSE
Copyright (C) 2004, 2005 Cees Hek <ceeshek@gmail.com>
This library is free software. You can modify and or distribute it
under the same terms as Perl itself.
|