implement user/password/csrf checks for login form
This commit is contained in:
parent
c6fd0a0efb
commit
856a66c0be
3 changed files with 103 additions and 28 deletions
63
index.pl
63
index.pl
|
@ -34,26 +34,28 @@ my %action_type = (
|
||||||
undo => 3,
|
undo => 3,
|
||||||
);
|
);
|
||||||
|
|
||||||
app->plugin(authentication => {
|
app->plugin(
|
||||||
autoload_user => 1,
|
authentication => {
|
||||||
session_key => 'foodor',
|
autoload_user => 1,
|
||||||
load_user => sub {
|
session_key => 'foodor',
|
||||||
my ($app, $uid) = @_;
|
load_user => sub {
|
||||||
if ($uid == 1) {
|
my ( $app, $uid ) = @_;
|
||||||
return {
|
if ( $uid == 1 ) {
|
||||||
name => 'derf',
|
return {
|
||||||
};
|
name => 'dev',
|
||||||
}
|
};
|
||||||
return undef;
|
}
|
||||||
},
|
return undef;
|
||||||
validate_user => sub {
|
},
|
||||||
my ($c, $username, $password, $extradata) = @_;
|
validate_user => sub {
|
||||||
if ($username eq 'derf' and $password eq 'hallo') {
|
my ( $c, $username, $password, $extradata ) = @_;
|
||||||
return 1;
|
if ( $username eq 'dev' and $password eq 'ohai' ) {
|
||||||
}
|
return 1;
|
||||||
return undef;
|
}
|
||||||
},
|
return undef;
|
||||||
});
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
app->defaults( layout => 'default' );
|
app->defaults( layout => 'default' );
|
||||||
|
|
||||||
|
@ -799,6 +801,27 @@ get '/x/login' => sub {
|
||||||
$self->render('login');
|
$self->render('login');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
post '/x/login' => sub {
|
||||||
|
my ($self) = @_;
|
||||||
|
my $user = $self->req->param('user');
|
||||||
|
my $password = $self->req->param('password');
|
||||||
|
|
||||||
|
if ( $self->validation->csrf_protect->has_error('csrf_token') ) {
|
||||||
|
$self->render(
|
||||||
|
'login',
|
||||||
|
invalid => 'csrf',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( $self->authenticate( $user, $password ) ) {
|
||||||
|
$self->redirect_to('/');
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$self->render( 'login', invalid => 'credentials' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
get '/x/register' => sub {
|
get '/x/register' => sub {
|
||||||
my ($self) = @_;
|
my ($self) = @_;
|
||||||
$self->render('register');
|
$self->render('register');
|
||||||
|
|
|
@ -1,18 +1,54 @@
|
||||||
|
% if (my $invalid = stash('invalid')) {
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
<div class="card red darken-4">
|
||||||
|
<div class="card-content white-text">
|
||||||
|
% if ($invalid eq 'csrf') {
|
||||||
|
<span class="card-title">Ungültiger CSRF-Token</span>
|
||||||
|
<p>Sind Cookies aktiviert? Ansonsten könnte es sich um einen
|
||||||
|
Fall von <a
|
||||||
|
href="https://de.wikipedia.org/wiki/Cross-Site-Request-Forgery">CSRF</a>
|
||||||
|
handeln.</p>
|
||||||
|
% }
|
||||||
|
% elsif ($invalid eq 'credentials') {
|
||||||
|
<span class="card-title">Ungültige Logindaten</span>
|
||||||
|
<p>Falscher Account oder falsches Passwort.</p>
|
||||||
|
% }
|
||||||
|
% else {
|
||||||
|
<span class="card-title">Unbekannter Fehler</span>
|
||||||
|
<p>Das sollte nicht passieren™</p>
|
||||||
|
% }
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
% }
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<form class="col s12">
|
%= form_for '/x/login' => (class => 'col s12', method => 'POST') => begin
|
||||||
|
%= csrf_field
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="input-field col s12">
|
<div class="input-field col s12">
|
||||||
<i class="material-icons prefix">account_circle</i>
|
<i class="material-icons prefix">account_circle</i>
|
||||||
<input id="user" type="text" class="validate">
|
<input name="user" id="user" type="text" class="validate">
|
||||||
<label for="user">User</label>
|
<label for="user">Account</label>
|
||||||
|
</div>
|
||||||
|
<div class="input-field col s12">
|
||||||
|
<i class="material-icons prefix">lock</i>
|
||||||
|
<input name="password" id="password" type="password" class="validate">
|
||||||
|
<label for="password">Passwort</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="input-field col s12">
|
<div class="col s3 m3 l3">
|
||||||
<i class="material-icons prefix">lock</i>
|
</div>
|
||||||
<input id="password" type="password" class="validate">
|
<div class="col s6 m6 l6 center-align">
|
||||||
<label for="password">Password</label>
|
<button class="btn waves-effect waves-light" type="submit" name="action" value="login">
|
||||||
|
Anmelden
|
||||||
|
<i class="material-icons right">send</i>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div class="col s3 m3 l3">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
%= end
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -36,3 +36,19 @@
|
||||||
</div>
|
</div>
|
||||||
%= end
|
%= end
|
||||||
</div>
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col s12">
|
||||||
|
<p>
|
||||||
|
Die Mail-Adresse wird ausschließlich zur Bestätigung der Anmeldung
|
||||||
|
und für die "Passwort vergessen"-Funktionalität verwendet und nicht
|
||||||
|
an Dritte weitergegeben. Weitere erhobene Daten sowie deren Zweck
|
||||||
|
und Speicherfristen werden in der <a
|
||||||
|
href="/x/impressum">Datenschutzerklärung</a> beschrieben.
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
Für jeden Account wird das Datum der letzten Anmeldung gespeichert.
|
||||||
|
Accounts, die mehr als ein Jahr (12 Monate) nicht genutzt wurden,
|
||||||
|
werden automatisch und unwiderruflich gelöscht.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue