(You are Anonymous)

CGI::Application::Plugin::Session Example

This is standalone program that demonstrates how to use CGI::Application::Plugin::Session out of the box.

Notice how the sending and parsing of the cookie is handled automatically. CGI::Application::Plugin::Session also handles setting up the local session store automatically.

CGI::Application::Plugin::Session also provides a session_config method if you do not like the defaults it chooses when configuring CGI::Session.

#!/usr/local/bin/perl
use warnings;
use strict;

TestApp->new->run;

package TestApp;
use base qw|CGI::Application|;
use CGI::Application::Plugin::AutoRunmode;
use CGI::Application::Plugin::Session;

sub default : StartRunmode {
  my $self = shift; my $output;

  # get current access count
  my $access_count = $self->session->param('access_count') || 0;

  # increment access count
  $access_count++;

  # store new access count in session
  $self->session->param(access_count => $access_count);

  # get CGI object out of application
  my $q = $self->query;

  #build output
  $output  = $q->start_html( -title => 'access count application');
  $output .= $q->div("accessed $access_count time(s) this session");
  $output .= $q->div(' ');
  $output .= $q->div( $q->a( { -href => $q->self_url } => 'access again' ) );
  $output .= $q->end_html;

  # give output to app to send to user
  return( $output );
}

Here is a multi-file example that uses MySQL to store sessions. The following table must exist in your database:

CREATE TABLE sessions (
   id CHAR(32) NOT NULL PRIMARY KEY,
   a_session TEXT NOT NULL
);

Note, if you are using the mysql_enable_utf8 database handle attribute the a_session field may need to be a BLOB instead of TEXT.

My files are arranged as such:

/html/myapp.cgi
/html/purge_old_sessions.cgi
/pc/modules/MyApp.pm
/pc/config/pc.cfg

Here is the instance script, myapp.cgi:

#!/usr/bin/perl -w -T
my $HOME_DIR;
BEGIN { $HOME_DIR = '../pc'; }
use strict;
use lib $HOME_DIR.'/modules';  # this is where I put MyApp.pm
use lib $HOME_DIR.'/lib/perl5/site_perl';  # this is where I installed Perl modules
use CGI::Carp qw(fatalsToBrowser);
use MyApp;

MyApp->new(
  ,-config_file	=> $HOME_DIR.'/config/pc.cfg'
)->run;

The config file, pc.cfg:

user             the_username
password         the_password
dsn              dbi:mysql:database=database_name:host=localhost
cgi_session_dsn  driver:mysql;serializer:Storable
cookie_path      /

The application file, MyApp.pm:

package MyApp;
use strict;
use base 'CGI::Application';
use CGI::Application::Plugin::AutoRunmode;
use CGI::Application::Plugin::Config::Simple;
use CGI::Application::Plugin::DBH (qw/dbh_config dbh/);
use CGI::Application::Plugin::Session;
sub cgiapp_init {
    my ($self, %params) = @_;
    # -- config
    $self->config_file($params{-config_file});
    $self->dbh_config(
         $self->config_param('dsn')
        ,$self->config_param('user')
        ,$self->config_param('password')
    );
    # -- session
    $self->session_config(
        CGI_SESSION_OPTIONS => [ 
           $self->config_param('cgi_session_dsn')
          ,$self->query
          ,{Handle=>$self->dbh} 
        ],
        DEFAULT_EXPIRY      => '+31d',  # should this match -expires below?  TBD
        COOKIE_PARAMS       => {
              -expires => '+31d'
             ,-path    => $self->config_param('cookie_path')
        }
    );
}
sub terminate {
   my $self = shift;
   $self->session->flush if $self->session_loaded;
   # CGI::Sesssion documentation says "auto-flushing can be unreliable.
   # ...regard it as mandatory that sessions always need to be explicitly 
   # flushed before the program exits... sub teardown() would be the 
   # appropriate place to do this.
}
sub display_form : StartRunmode {
   my $self = shift;
   my $q = $self->query;
   my $session_data = $self->session->param('stuff') || 1;
   my $result = $q->start_html(-title => 'Client Login')
      . $q->start_form
      . 'First Name: ' . $q->textfield(-name=>'firstName')
      . $q->br . $q->submit
      . $q->hidden(-name =>'rm', -value => 'page_2')
      . $q->end_form
      . $q->br . $session_data
      . $q->end_html
   ;
   $session_data++;  # reload the page to see the value change above
   $self->session->param(stuff=>$session_data);
   return $result;
}

Use this script, purge_old_sessions.cgi, to periodically purge old sessions from the database.

#!/usr/bin/perl
use strict;
use warnings;

my $HOME_DIR;
BEGIN { $HOME_DIR = '../pc'; }  # I installed Perl modules here
use lib $HOME_DIR.'/lib/perl5/site_perl';
use Config::Simple;
use CGI::Session::ExpireSessions;
use DBI;
use CGI::Carp qw(fatalsToBrowser);
use CGI qw(:standard);

use constant DAYS => 30;

print header
  ,p('Removing sessions that are more than '.DAYS.' days old.')
  ,pre;
my $cfg = Config::Simple->new($HOME_DIR.'/config/pc.cfg');
CGI::Session::ExpireSessions->new(
       delta => DAYS * 24 * 60 * 60  # seconds
##	 delta => 2  # use for testing -- expire sessions that 
                   # haven't been accessed in the last 2 seconds
      ,verbose => 1
      ,cgi_session_dsn => $cfg->param('cgi_session_dsn')
      ,dsn_args => {
            DataSource => $cfg->param('dsn')
            ,User      => $cfg->param('user')
            ,Password  => $cfg->param('password')
      }
)->expire_sessions;