Search code examples
perlauthenticationplackstarman

How do you use Plack::Middleware::Session with a Starman Server?


I have a Starman based server -

#!/usr/bin/perl
use strict;
use warnings;
use Data::Printer;
use Plack::Builder;

my $app = sub {
    my $env = shift;
    my $session = $env->{'psgix.session'};

    # Print environment variables
    p($env);

    return [
        200,
        [ 'Content-Type' => 'text/plain' ],
        [ "Hello, you've been here for ", $session->{counter}++, "th   time!" ],
    ];
};

my $default = sub {
    my $env = shift;
    p($env);
    return [
        '200', [ 'Content-Type' => 'text/html' ],
        ["Welcome to default page"],
    ];
};

builder {
    mount "/validate" => builder {
        enable "Middleware::Authentication"
        enable "Session";
        $app;
    };
    mount "/" => builder { $default };
};

My own middleware "Authentication" authenticate the user and return session information(expiry time, session key etc) for the session management, So how can i make use of these information in the Session Middleware?


Solution

  • If I understand right, your problem is only in the order of the middleware. Enable the Session before your Auth.

    Check the following, using the File storage, the sessions are stored persistently. Try it, restart your Starman and the counter will be reloaded. (I using inline middleware as an replacement to your Authentication.)

    #!/usr/bin/env perl
    use strict;
    use warnings;
    use Data::Printer;
    use Plack::Builder;
    
    my $app = sub {
        my $env = shift;
        my $session = $env->{'psgix.session'};
        return [
            200,
            [ 'Content-Type' => 'text/html' ],
            [
                "My app page is visited ",
                $session->{counter}++,
                "th times! Validation is done at:",
                $session->{mwaretime},
                q{<br><a href="/validate">go validate again</a> --- <a href="/">reload this page</a>}
            ],
        ];
    };
    
    my $validate = sub {
        my $env = shift;
        my $session = $env->{'psgix.session'};
        $session->{counter} = 0;
        return [
            '200', [ 'Content-Type' => 'text/html' ],
            [
                "Resetting the counter:",
                $session->{counter},
                 ". Time from middleware: ",
                $session->{mwaretime},
                q{<br> <a href="/validate">reload this page</a> --- <a href="/">go to index</a> }
            ],
        ];
    };
    
    builder {
        #the session will be stored persistently
        #enable the Session BEFORE your middleware
        enable 'Session', store => 'File';
    
        mount "/validate" => builder {
            #enable "Authentication";
            #following is same as an middleware
            enable sub {
                my $app = shift;
                return sub {
                    my $env = shift;
                    my $session = $env->{'psgix.session'};
                    $session->{mwaretime} = time();
                    $app->($env);
                };
            };
            #end of the middleware
            $validate;
        };
        mount "/" => $app 
    };