The examples on this site are currently tested to work on Phalcon V3.4 and Phalcon Devtools V3.2 Some issues may arise when using later versions.

Please get in touch or post a comment below the post if you encounter a problem.

Now that we have the ability to create users we need to allow users login to the system. To do this we need to:

Firstwe need the login form itself. The following file uses the volt templating engine. Normally I use phtml file as that is what is generated by the scaffolder by default. It is possible to make the scaffolder to generate volt. Volt, is very similar to many other templating languages that are used in modern web development that use the "double moustache" {{ to create placeholders. There's a lot of benefits to a language such as this particularly for people who are not already proficient with PHP. Volt can be explored in more detail in a later post. This example is a suitable introduction to volt as the form is small. Save the following file as app/views/user/login.volt

{{ content() }}
<div class="page-header">
    <h3>Log In</h3>
</div>
{{ form('user/authorize', 'role': 'form') }}
    <fieldset>
        <div class="form-group">
            <label for="username">Username</label>
            <div class="controls">
                {{ text_field('username', 'class': "form-control") }}
            </div>
        </div>
        <div class="form-group">
            <label for="password">Password</label>
            <div class="controls">
                {{ password_field('password', 'class': "form-control") }}
            </div>
        </div>
        <div class="form-group">
            {{ submit_button('Login', 'class': 'btn btn-primary btn-large') }}
        </div>
    </fieldset>
{{  endform() }}

To get this form to render there needs to be a corresponding action in the UserController - add the following empty function to apps/controllers/UserController.php

public function loginAction()
{

}

If we're going to have a login action we should also have a logout action which destroys the session. Once we start to use sessions having the ability to destroy session information becomes important. Otherwise we'll find it hard to test changes and updates as the system will be picking up on old session information. Add the following logoutAction() function to /apps/controllers/UserController.php

public function logoutAction()
{
    $this->session->destroy();
    return $this->dispatcher->forward(["controller" => "member","action" => "search"]);
}

Finally we need a function in the UserController to authorize the login - add the following function to app/controllers/UserController.php

public function authorizeAction()
{
    $username = $this->request->getPost('username');
    $pass= $this->request->getPost('password');
    $user=User::findFirstByUsername($username);
    if ($user) {
        if ($this->security->checkHash($pass, $user->getpassword())) {
            $this->session->set('auth',
            ['userName' => $user->getusername(), 
             'role' => $user->getRole()]);
            $this->flash->success("Welcome back " . $user->getusername());
            return $this->dispatcher->forward(["controller" => "member","action" => "search"]);
        }
        else {
            $this->flash->error("Your password is incorrect - try again");
            return $this->dispatcher->forward(["controller" => "user","action" => "login"]);
        }
    }
    else {
        $this->flash->error("That username was not found - try again");
        return $this->dispatcher->forward(["controller" => "user","action" => "login"]);
    }
    return $this->dispatcher->forward(["controller" => "index","action" => "index"]);
}

The program checks the password against the hashed version stored in the database. It's worth noting that phalcon uses bcrypt here which provides good security against brute force attacks. It's also possible to change the workfactor of bcrypt by including Security settings in the services.php file. As time passes and computers become more powerful it may be necessary to change this to reduce the likely success of a brute force attack.

If the username and password are correct the function will set the username and role as session variables and send the user back to the member/search page with a welcome back message.

Setting the role is important as that will determine which aspects of the functionality of the system the user will be permitted to access. How to lock users out from certain controllers/actions is discussed in subsequent posts.

If the password is incorrect or the username is not found the user will be redirected back to the login screen with an appropriate error message.