But, if I dont misunderstand myself, I have not duplicated code in the actual code: the IP check and the authentication only happens in get_first while in <c>get_second only a cookie is checked, no?
Well yes, but since http is stateless, what happens if get_second gets called first?
I'm developing some Mojolicious::Lite apps at the time, and my layout is as follows
#!/usr/bin/perl
use Mojolicious::Lite;
use Foo::Blargh; # yadda yadda, other usefull stuff
get "/login" => sub {
my $c = shift; # $c is the controller object
$c->render('login'); # renders templates/login.html.ep
};
# this sub checks username and password
post "/login" => sub {
validate_user(shift); # the sub gets the controller
};
get "/logout" => sub {
my $c = shift;
$c->cookie(MySession => 'none'); # unset cookie
$c->redirect_to("/login");
};
# with the following, all following routes require
# a logged-in user and a proper cookie
under sub {
validate_cookie(shift);
};
# more routes
get "/foo" => sub {
my $c = shift;
...
$c->render($whatever);
};
get "/bar" => sub {
my $c = shift;
...
$c->render($something_else);
};
# all set up, start the application;
app->start;
###
##
# subs
sub validate_cookie {
my $c = shift;
my $cookie = $c->cookie('MySession');
if (! $cookie) {
$c->redirect_to('/login');
return; # important!
} else {
# more checks to see if cookie is valid
...
}
1;
}
sub validate_user {
my $c = shift;
my $u = $c->param('user');
my $p = $c->param('pass');
if ( login($u,$p) ) {
# set cookie. Multiple cookies can be set by calling
# $c->cookie() with other key/value pairs more than 1 time
$c->cookie(MySession => generate_cookie() );
$c->redirect_to('/foo'); # whatever is appropriate
return;
}
$c->stash(error => 'wrong user or password'); # gets rendered in /
+login
$c->render('login');
return;
}
sub login {
# validate user and password: database, ldap, ...
# returns 1 on success, nothing on failure
}
sub generate_cookie {
my $n = shift || 42;
my @chars = ('A'..'Z','a'..'z',0..9,'+','/' ); # we use the BASE64
+ chars
join '', map{ $chars[rand @chars] }1..$n; # session ID
}
Works for me ;-)
perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'