API development

As we already discussed, we need to extend the API to be able to validate the credentials of a user and return a proper response to the client.

Requirements

The requirements at the API level are as follows:

  • Add a new endpoint called /api/users/login
  • Process the information posted there to check the credentials using bcrypt, which we already discussed in Chapter 10, Sign Up.

Overview of the module structure

As we did in the previous chapter, we are going to work on the Users module, and we will add a new controller. The following screenshot shows us how the folders are organized:

Overview of the module structure

The module.config.php file

We need to do a couple of changes in this file to receive requests, with the following code:

'login' => array(
    'type' => 'ZendMvcRouterHttpLiteral',
    'options' => array(
        'route' => '/api/users/login',
        'defaults' => array(
            'controller' => 'UsersControllerLogin'
        ),
    ),
),

This is the new route we need to declare in order to fulfill the login requests. Because we are adding a new controller, we should also specify the name of the controller in the controllers/invokable section as follows:

'controllers' => array(
    'invokables' => array(
        'UsersControllerIndex' =>
            'UsersControllerIndexController',
        'UsersControllerLogin' =>
            'UsersControllerLoginController',
    ),
),

Creating the LoginController.php file

In this controller, we are going accept the credentials as post parameters. Because we are doing everything by extending AbstractRestfulController, we should place our code in the create() method, even if we are not exactly creating something.

As we need to verify the password using the bcrypt component, we need to add the dependency at the top of the file after defining the following namespace:

use ZendCryptPasswordBcrypt;

After we declare the class, we also need to declare a new property, which will hold the user's table and also the method to load the table gateway. At this point of time, you should be able to complete those two tasks by yourself, but if you have to struggle to do it, do not hesitate to check the following source code:

public function create($data)
{
    $usersTable = $this->getUsersTable();
    $user = $usersTable->getByUsername($data['username']);

    $bcrypt = new Bcrypt();
    if (!empty($user) &&$bcrypt->verify(
    $data['password'], 
    $user->password)
    ) {
        $result = new JsonModel(array(
            'result' => true,
            'errors' => null
        ));
    } else {
        $result = new JsonModel(array(
            'result' => false,
            'errors' => 'Invalid Username or password'
        ));
    }

    return $result;
}

These are the contents of the create() method. As you can see, we get the data of the user from the database. If the user exists, we verify the password sent by the client against the password stored in the database. Each time you encrypt a password with bcrypt, the hash will be different, and that's why you cannot just do a simple comparison; you must use the verify() method from the Bcrypt component, which will take care of checking if the passwords match or not and return a true/false result. Then, it is just a matter of sending a true or false value to the client.

As we are again using sensible information, we should do this under the HTTPS protocol in a production-ready project to ensure that the plain text password is encrypted by the HTTPS protocol and kept safe when sending it to the server.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.108.236