Mojolicious
view release on metacpan or search on metacpan
lib/Mojolicious/Guides/Growing.pod view on Meta::CPAN
# Test if the HTML login form exists
$t->get_ok('/')
->status_is(200)
->element_exists('form input[name="user"]')
->element_exists('form input[name="pass"]')
->element_exists('form input[type="submit"]');
# Test login with valid credentials
$t->post_ok('/' => form => {user => 'sebastian', pass => 'secr3t'})
->status_is(200)
->text_like('html body' => qr/Welcome sebastian/);
# Test accessing a protected page
$t->get_ok('/protected')->status_is(200)->text_like('a' => qr/Logout/);
# Test if HTML login form shows up again after logout
$t->get_ok('/logout')
->status_is(200)
->element_exists('form input[name="user"]')
->element_exists('form input[name="pass"]')
->element_exists('form input[type="submit"]');
done_testing();
Your application won't pass these tests, but from now on you can use them to check your progress.
$ prove -l
$ prove -l t/login.t
$ prove -l -v t/login.t
Or perform quick requests right from the command line with L<Mojolicious::Command::get>.
$ ./myapp.pl get /
Wrong username or password.
$ ./myapp.pl get -v '/?user=sebastian&pass=secr3t'
GET /?user=sebastian&pass=secr3t HTTP/1.1
User-Agent: Mojolicious (Perl)
Accept-Encoding: gzip
Content-Length: 0
Host: localhost:59472
HTTP/1.1 200 OK
Date: Sun, 18 Jul 2010 13:09:58 GMT
Server: Mojolicious (Perl)
Content-Length: 12
Content-Type: text/plain
Welcome sebastian.
=head2 State keeping
Sessions in L<Mojolicious> pretty much just work out of the box once you start using the method
L<Mojolicious::Controller/"session">, there is no setup required, but we suggest setting a more secure passphrase with
L<Mojolicious/"secrets">.
app->secrets(['Mojolicious rocks']);
This passphrase is used by the HMAC-SHA256 algorithm to make signed cookies tamper resistant and can be changed at any
time to invalidate all existing sessions.
$c->session(user => 'sebastian');
my $user = $c->session('user');
By default all sessions expire after one hour, for more control you can use the C<expiration> session value to set an
expiration date in seconds from now.
$c->session(expiration => 3600);
And the whole session can be deleted by using the C<expires> session value to set an absolute expiration date in the
past.
$c->session(expires => 1);
For data that should only be visible on the next request, like a confirmation message after a C<302> redirect performed
with L<Mojolicious::Plugin::DefaultHelpers/"redirect_to">, you can use the flash, accessible through
L<Mojolicious::Plugin::DefaultHelpers/"flash">.
$c->flash(message => 'Everything is fine.');
$c->redirect_to('goodbye');
Just remember that all session data gets serialized with L<Mojo::JSON> and stored in HMAC-SHA256 signed cookies, which
usually have a C<4096> byte (4KiB) limit, depending on browser.
=head2 Final prototype
A final C<myapp.pl> prototype passing all of the tests above could look like this.
#!/usr/bin/env perl
use Mojolicious::Lite -signatures;
use lib qw(lib);
use MyApp::Model::Users;
# Make signed cookies tamper resistant
app->secrets(['Mojolicious rocks']);
helper users => sub { state $users = MyApp::Model::Users->new };
# Main login action
any '/' => sub ($c) {
# Query or POST parameters
my $user = $c->param('user') || '';
my $pass = $c->param('pass') || '';
# Check password and render "index.html.ep" if necessary
return $c->render unless $c->users->check($user, $pass);
# Store username in session
$c->session(user => $user);
# Store a friendly message for the next page in flash
$c->flash(message => 'Thanks for logging in.');
# Redirect to protected page with a 302 response
$c->redirect_to('protected');
} => 'index';
# Make sure user is logged in for actions in this group
( run in 2.363 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )