use strict; use warnings; use Mojolicious::Lite; plugin 'ClientIP'; plugin 'basic_auth_plus'; # sample data for authentication my %accepted_IPs = ( '8.8.8.8' => 1 ); my %users = ( usr1 => 'pwd1', usr2 => 'pwd2'); # sample data to send back to client my $text_a = 'Né più mai toccherò le sacre sponde'; my $text_b = 'ove il mio corpo fanciulletto giacque,'; # I expect all non specified routes to answer 404, right? # get text_a. Steps 2) and 3) of the above description get '/get_first' => sub { my $self = shift; my $remote_IP = $self->client_ip; # check username and password my ($href, $auth_ok) = $self->basic_auth( realm => sub { # @_ contains username and password if ( exists $users{$_[0]} and $users{$_[0]} eq $_[1]){ # log the correct login $self->log->info( "$_[0] from $remote_IP login OK" ); return 1; } } ); # reject unwanted remote IP unless ( exists $accepted_IPs{ $remote_IP } ){ # log unwanted IP $self->log->warn( "$href->{username} logged from unwanted IP: $remote_IP" ); # reject the request return $self->render( status => 401, text => 'unauthorized', ) } # process the request.. if ( $auth_ok ) { # set the session cookie valid for 2 minutes $self->session( expiration => 120, is_my_user_authenticated => 1 ); # log the action $self->log->info( "sent TEXT_A to $remote_IP" ); # render TEXT_A return $self->render( status => 200, text => $text_a, ); } # .. or reject it else { # log a failed attempt $self->log->warn( "bad login attempt from valid IP $remote_IP using user $href->{username}" ); # reject return $self->render( status => 401, text => 'unauthorized', ); } }; # get text_b. Steps 6) and 7) of the above description get '/get_second' => sub { my $self = shift; my $remote_IP = $self->client_ip; # check the previously set cookie session if ( $self->session( 'is_my_user_authenticated') == 1 ) { # expire the session cookie $self->session( expires => 1, is_my_user_authenticated => 0 ); # log the action $self->log->info( "sent TEXT_B to $remote_IP" ); # render TEXT_B return $self->render( status => 200, text => $text_b, ); } else { # log the action $self->log->warn( "unexpected request of TEXT_B from $remote_IP: rejected ". "authenticated: $self->session( 'is_my_user_authenticated') ". "expiration: $self->session( 'expiration')"); # reject return $self->render( status => 401, text => 'unauthorized', ); } }; app->start;