{ use strict; use warnings; package LoginApp; use parent qw/Plack::Component/; use Plack::Util::Accessor qw( secure check_pass render_login ); use Plack::Response; use Plack::Request; sub call { my($self, $env) = @_; my $login_error; if( $self->secure && $env->{'psgi.url_scheme'} ne 'https' ){ my $res = Plack::Response->new; my $secure_url = 'https://' . $env->{SERVER_NAME} . $env->{PATH_INFO}; $res->redirect( $secure_url ); return $res->finalize; } my $params = Plack::Request->new( $env )->parameters; if( defined $env->{user} ){ return 'Already logged in'; } elsif( $env->{REQUEST_METHOD} eq 'POST' ){ my $user_id; ( $login_error, $user_id ) = $self->check_pass->( $params->get( 'username' ), $params->get( 'password' ) ); if( !$login_error ){ $env->{'psgix.session'}{user_id} = $user_id; $env->{'psgix.session'}{remember} = 1 if $params->get( 'remember' ); my $res = Plack::Response->new; my $redir_to = delete $env->{'psgix.session'}{redir_to}; $redir_to = '/' if URI->new( $redir_to )->path eq $env->{PATH_INFO} || !length( $redir_to ); $res->redirect( $redir_to ); return $res->finalize; } } $env->{'psgix.session'}{redir_to} ||= $env->{HTTP_REFERER}; my $render = $self->render_login || \&login_page; return [ 200, { 'Content-Type' => 'text/html', }, [ $render->( username => $params->get( 'username' ), login_error => $login_error, redir_to => $env->{'psgix.session'}{redir_to}, ) ] ]; } sub login_page { my ( %params ) = @_; my $out = "
\n"; if( $params{login_error} ){ $out .= "