Tudor Constantin
Tudor Constantin

Reputation: 26861

Mojolicious custom sessions

I am trying to use database sessions with Mojolicious instead of the builtin ones that are working with signed cookies.

In the startup subroutine I have something like:

my $dbh = DBI->connect(                                                                                                                                  
                        $config->{database}->{dsn},                                                                                                      
                        $config->{database}->{user},                                                                                                     
                        $config->{database}->{password},
                      );

my $session = MojoX::Session->new(
    store     => [dbi => {dbh => $dbh}],  # use MojoX::Session::Store::Dbi
    transport => 'cookie',                # this is by default
    ip_match  => 1
);

(ref($self))->attr( 'session' => sub {                
                return $session;
                } );

And I want to use the session object like $self->session or $self->app->session in controllers.

Unfortunately it doesn't work - it uses previous sessions (from different browsers).

This drives me crazy - all I tried today was to make this work - I've read all the documentation available, also the source of MojoX::Session and all its related classes, tried in about 923847293847239847 ways to make it work, but nothing seems to do it.

PS: I created the session table in the db.

Do you know what I should do in order to be able to use DB sessions with Mojolicious?

Upvotes: 4

Views: 2530

Answers (3)

Taras
Taras

Reputation: 920

You can connect MojoX::Session to the application as a plugin in a startup function.

use Mojolicious::Plugin::Session;

[...]

sub startup {
  my $self = shift;

  [...]

  $self->plugin( session => {
    stash_key => 'mojox-session',
    store     => [dbi => {dbh => $dbh}],  # use MojoX::Session::Store::Dbi
    transport => 'cookie',
    ip_match  => 1
  });

  [...]

Afterwards, you'll have access to session through stash key 'mojox-session' in controllers.

For example:

$self->stash('mojox-session')->data('something');

Upvotes: 6

xyz
xyz

Reputation: 41

You can use whatever sort of session backend you like. Just create your own controller base class derived from Mojolicious::Controller and override session(), like so:

package NiceController;
use Mojo::Base 'Mojolicious::Controller';
sub session { # custom code here }
1;

then in startup(), set your controller class as the default:

$self->controller_class('NiceController');

Finally, make sure your application controllers inherit from NiceController instead of Mojolicious::Controller

It's probably a good idea to make your overridden session() function work just like the built-in one, to avoid future confusion.

-xyz

Upvotes: 4

lhagemann
lhagemann

Reputation: 1268

The $app->session method is reserved for using the built-in sessions.

You should take a look at the Mojolicious helpers and you probably want to use a different method name to avoid conflict.

Upvotes: 1

Related Questions