Crear una REST API con autenticación usando Laravel [Capítulo 2]

Esta entrada es la segunda de una serie de artículos sobre Laravel, uno de los frameworks PHP más populares del momento.

En el capítulo anterior aprendimos a crear la estructura básica de una aplicación Laravel, a conectarla con una base de datos, a poblar las tablas y a implementar las rutas y controladores básicos para soportar una operativa CRUD básica.

El objetivo de estos artículos es aprender a construir una REST API con autenticación usando Laravel 5.5. Para ello utilizaremos Composer, el gestor de paquetes y dependencias de PHP, y Artisan, una interfaz de línea de comandos que viene con Laravel.

Todo el código necesario para seguir este capítulo y construir la REST API con autenticación se encuentra en GitHub.

CONTENIDO

En este segundo artículo abordaremos los siguientes puntos:

AUTENTICACIÓN API EN LARAVEL

Hay varias formas de implementar Autenticación API en Laravel, una de ellas Passport, una forma sencilla de implementar Oauth2, pero en este artículo vamos a hacer una aproximación más sencilla.

Esquema general autenticación API
Esquema general autenticación API

Para empezar, vamos a añadir un nuevo campo ‘api_token‘ a nuestra tabla ‘users‘:

$ php artisan make:migration --table=users adds_api_token_to_users_table

Y a continuación, implementamos la migración en el fichero ‘./laravel-api/database/migrations/2017_10_31_162358_adds_api_token_to_users_table.php‘ que se ha generado:

Después simplemente tenemos que ejecutar la migración:

$ php artisan migrate

Y ya vemos el nuevo campo en la base de datos:

Tabla de Usuarios con token
Tabla de Usuarios con token

REGISTRO DE UN NUEVO USUARIO

Vamos a utilizar el Controlador RegisterController que se encuentra en la ruta ./laravel-api/app/Http/Controllers/Auth/ para devolver la respuesta correcta a las peticiones de registro.

El controlador utiliza la característica ‘RegisterUsers‘ para implementar el registro. Así es como funciona:

public function register(Request $request)
{
    // Here the request is validated.
    // The validator method is located inside the
    // RegisterController, and makes sure the name, email
    // password and password_confirmation fields are required.
    $this->validator($request->all())->validate();

    // A Registered event is created and will trigger any relevant
    // observers, such as sending a confirmation email or any
    // code that needs to be run as soon as the user is created.
    event(new Registered($user = $this->create($request->all())));

    // After the user is created, he's logged in.
    $this->guard()->login($user);

    // And finally this is the hook that we want. If there is no
    // registered() method or it returns null, redirect him to
    // some other URL. In our case, we just need to implement
    // that method to return the correct response.
    return $this->registered($request, $user)
                    ?: redirect($this->redirectPath());
}

Implementamos el método ‘registered()‘ en el mismo controlador. El método recibirá los parámetros $request y $user:

Y lo enlazamos en el fichero de rutas (./laravel-api/routes/api.php):

Route::post('register', 'Auth\RegisterController@register');

En el método ‘registered()‘ hemos llamado al método ‘generateToken()‘ del Usuario para generar el token. Lo añadimos al modelo de Usuario (laravel-api/app/User.php):


Y ya está. El usuario ya está registrado, y gracias al sistema de validación que viene de serie con Laravel se requerirán automáticamente los campos ‘name‘, ‘email‘, ‘password‘ y ‘password_confirmation‘.

Si ahora accedemos a la ruta correspondiente de nuestra API pasándole los parámetros requeridos, obtendríamos el token correspondiente:

[POST] http://localhost:8080/api/register

Postman Register
Postman Register

IDENTIFICACIÓN DE USUARIO

Al igual que hemos hecho en el punto anterior, tan solo tendremos que editar el controlador de login (./laravel-api/app/Http/Controllers/Auth/LoginController.php) para añadirle soporte de autenticación. Deberemos sobreescribir el método ‘login‘ que el controlador hereda de AuthenticateUsers:

Y lo enlazamos en el fichero de rutas (./laravel-api/routes/api.php):

Route::post('login', 'Auth\LoginController@login');

Podemos probar la llamada a la API:

[POST] http://localhost:8000/api/login
Postman Login
Postman Login

Para adjuntar el token en cualquier petición que hagamos a la API, se puede hacer como “bearer token” en las cabeceras de la petición:

Authorization: Bearer rFObzPd5IYNlowBNUPdOrpIyu1dMILQV2NtFK8l8sDhdv0BaaYPcgSRL6SqZ

DESCONEXIÓN DE USUARIO

Para implementar el cierre de sesión, añadimos un método ‘logout()‘ al controlador de login (./laravel-api/app/Http/Controllers/Auth/LoginController.php) que borrará el token de la base de datos:

Y lo enlazamos en el fichero de rutas (./laravel-api/routes/api.php):

Route::post('logout', 'Auth\LoginController@logout');

De esta forma, cualquier token que envíe el usuario una vez éste se ha desconectado resultará inválido. Para ello deberemos hacer uso de los ‘middleware‘, tal como veremos en el siguiente punto.

Todo esto requiere una coordinación efectiva con la aplicación cliente para evitar que el usuario continúe identificado sin tener acceso a ningún contenido.

USAR MIDDLEWARE PARA RESTRINGIR ACCESO

Un middleware es un mecanismo que proporciona Laravel desde su versión 5 para filtrar las peticiones HTTP que llegan a nuestra aplicación.

El uso más extendido de middleware es el relacionado con la autenticación de usuarios en la aplicación. Se encarga de comprobar si el usuario que hace la petición está identificado y tiene permisos. También se pueden utilizar para, por ejemplo, inyectar cabeceras a las respuestas, hacer log de peticiones, protección para ataques, etc.

Para añadir un middleware de autenticación a las rutas de nuestro API, tan solo debemos anidarlas dentro de un grupo de rutas de la siguiente manera:

Si ahora intentáramos recuperar todos los artículos mediante una petición GET:

[GET] http://localhost:8000/api/articles

Obtendríamos el siguiente error:

Route [login] not defined.
Postman Middleware
Postman Middleware

Es necesario definir el método ‘unathenticated()‘ del manejador de excepciones (./laravel-api/app/Exceptions/Handler.php) para que devuelva una cabecera JSON adecuada:

Y ahora la petición nos retornará un código HTML más adecuado:

Postman Middleware
Postman Middleware

RECOPILACIÓN

En este segundo artículo de la serie “Crear una REST API con autenticación usando Laravel” hemos aprendido a implementar un sencillo método de autenticación de usuarios para registrar, identificar y desconectar usuarios a nuestra API. Además nos hemos introducido en el uso de middlewares para restringir el acceso a las rutas a los usuarios no identificados.

En el siguiente artículo veremos cómo integrar nuestra API con PHPUnit para realizar pruebas unitarias. El objetivo de estas pruebas es verificar el correcto funcionamiento de cada parte de la aplicación, e identificar problemas en las fases iniciales del desarrollo.

Si tienes cualquier duda o problema a la hora de comprender alguno de los pasos, exponla en los comentarios y te responderé. Y si ya tienes experiencia haciendo REST API‘s o con Laravel, te invito a compartir tu experciencia e impresiones sobre este artículo en los comentarios. Compartamos conocimiento y ¡crezcamos juntos!

Desarrollo WebSoftware Libre