Authentication

The skeleton app comes with a lightweight authentication library that can validate users against SQL databases using PDO, against Active Directory/LDAP, or you can use a simple Text validation adapter. The auth object is defined in the dependencies file. You can modify the settings there. All the documentation for setting up the authentication object and the different adapters is available on the Vespula/Auth documentation.

First you need to set up a few routes to match the login requests (one via GET and one via POST), and the logout request. In your project's routes.php file, add the following:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
<?php
// Replace "Project" with the name of your project

$app->group('/login', function () {
    $this->get('', function($request, $response) {
        $controller = new \Project\Controllers\Index($this, $request, $response);
        return $controller->login();
    });
    $this->post('', function($request, $response) {
        $controller = new \Project\Controllers\Index($this, $request, $response);
        return $controller->doLogin();
    });
});

$app->get('/logout', function ($request, $response) {
    $controller = new \Project\Controllers\Index($this, $request, $response);
    return $controller->logout();
});

Next, you need actions in the controller you described in the routes for login(), doLogin(), and logout().

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
<?php

namespace Project\Controllers;
class Index extends Controller {
// ...

    public function login()
    {
        // you should use a csrf strategy here too. Aura Session (included) has csrf tools.
        $content = $this->view->render('index/login', [
            'messages'=>$this->messages
        ]);
        return $this->response->write($content);
    }

    public function doLogin()
    {
        $username = filter_input(INPUT_POST, 'username', FILTER_SANITIZE_STRING);
        $password = filter_input(INPUT_POST, 'password', FILTER_DEFAULT);
        $password = strip_tags($password);
        $credentials = [
            'username'=>$username,
            'password'=>$password
        ];
        $this->auth->login($credentials);
        if ($this->auth->isValid()) {
            $this->setFlash('info', 'You are logged in');
            $this->log->info($username . ' logged in');
            return $this->redirect('/');
        } else {
            $this->setFlash('error', 'bad login');
            $this->log->error($username . ' failed to log in');
            return $this->redirect('/login');
        }
    }

    public function logout()
    {
        $username = $this->auth->getUsername();
        $this->auth->logout();
        if ($this->auth->isAnon()) {
            $this->setFlash('info', 'Goodbye');
            $this->log->info($username . ' logged out');
            return $this->redirect('/');
        } else {
            $this->setFlash('error', 'Could not log you out...');
            $this->log->error($username . ' failed logging out');
            return $this->redirect('/');
        }
    }
}

Some other checks might be worthwhile for authentication status. For example, you might want to know if the person has been idle for too long, or they have gone past the expire time for the session. You can set those check up in your base controller's constructor.

1
2
3
4
5
6
7
if ($this->auth->isIdle()) {
    // flash message, etc
}

if ($this->auth->isExpired()) {
    // flash some message
}

Any time you want to check if the user is valid, just call the $this->auth->isValid(). Within views, you can call $auth->isValid().

Login Template

Your login template index/login.php in the Views folder might look like this bootstrap-flavoured one:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php $this->layout('layouts::' . $theme); ?>

<?php echo $this->alerts($messages); ?>
<?php if ($auth->isValid()) : ?>
<p>You are already logged in! How special for you!</p>
<?php else : ?>
<h2>Login</h2>
<div class="row">
    <div class="col-lg-2">
        <form action="" method="post">
            <div class="form-group">
                <label for="username">Username</label>
                <input type="text" class="form-control" name="username" id="username" placeholder="Username" />
            </div>
            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" class="form-control" name="password" id="password" placeholder="Password" autocomplete="off" />
            </div>
            <input type="submit" class="btn btn-primary" value="Login" />
        </form>
    </div>
</div>
<?php endif; ?>