Crea una API Rest con Autenticación 🔥 Laravel y Passport
Tiempo de lectura: 3.62 minutos
Hoy vamos a desarrollar una API Rest usando Laravel y Passport.
La configuración es más sencilla de lo que parece.
Sólo ten en cuenta que para seguir esta guía necesitas de Laravel 5.8 o superior.
Paso 1. Crear un proyecto Laravel nuevo
Puedes crear el proyecto Laravel usando Composer:
composer create-project --prefer-dist laravel/laravel auth
O si eres de los que prefiere Laravel Installer, puedes hacer lo mismo con laravel new auth
.
Como ves:
- En este caso,
auth
es el nombre del proyecto. - Pero si ya tienes uno creado, puedes seguir los pasos allí.
Si vas a trabajar con un proyecto nuevo, recuerda que también debes configurar las credenciales de acceso a tu base de datos.
Por ejemplo, puedes crear una base de datos llamada "auth", y entonces definir en tu archivo .env
:
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=auth
DB_USERNAME=root
DB_PASSWORD=
Paso 2. Instalar el paquete Laravel Passport
Laravel Passport nos permite configurar un servidor de OAuth2 sobre nuestro Laravel en muy poco tiempo.
composer require laravel/passport
Paso 3. Ejecutar las migraciones
El paquete Passport, al descargarse, incluye migraciones.
Es importante ejecutar estas migraciones, para contar con las tablas necesarias para guardar información de los clients
y access tokens
:
php artisan migrate
Si no entiendes muy bien de qué estoy hablando es porque no estás familiarizado con el protocolo OAuth2.
En ese caso:
- Te recomiendo empezar por este artículo sobre OAuth2.
- Y si deseas profundizar, puedes seguir este curso de OAuth 2 ?.
Paso 4. Generar llaves
Para que nuestro proyecto pueda generar access tokens
seguros es necesario contar con encryption keys
(llaves que se usan en el proceso de encriptación).
Para ello debemos ejecutar:
php artisan passport:install
Este comando además va a crear clients
, que luego podemos usar para generar access tokens
:
Paso 5. Configuración de Passport
Ahora debes agregar el trait Laravel\Passport\HasApiTokens
a tu modelo App\User
.
Este trait habilita métodos para el modelo, que te permitirán inspeccionar el token del usuario autenticado y sus scopes
correspondientes.
<?php namespace App;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;
class User extends Authenticatable
{
use Notifiable, HasApiTokens;
// ...
}
Para que Passport funcione correctamente también debes habilitar sus rutas.
Para esto basta con llamar el método Passport::routes
dentro del AuthServiceProvider
de tu proyecto.
Específicamente dentro del método boot
.
Estas rutas permiten a Passport hacer issue
y revoke
de access tokens
y clients
.
<?php namespace App\Providers;
use Laravel\Passport\Passport;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
// ...
public function boot()
{
$this->registerPolicies();
Passport::routes(); // <---
}
}
Con esto listo ya puedes ir a tu archivo de configuración config/auth.php
y asignar el driver "passport" para el authentication guard
llamado "api":
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'passport', // <---
'provider' => 'users',
],
],
De esta manera, Passport se encargará de validar las peticiones entrantes a la API.
Hasta aquí ya tenemos Laravel Passport configurado correctamente.
Sin embargo, la pregunta es:
¿cómo podemos usar Passport y definir las primeras rutas de nuestra API?
Veamos ello a continuación.
Paso 6. Definir las rutas principales para la API
Sólo debes dirigirte al archivo routes/api.php
, y agregar allí:
Route::group([
'prefix' => 'auth'
], function () {
Route::post('login', 'AuthController@login');
Route::post('signup', 'AuthController@signUp');
Route::group([
'middleware' => 'auth:api'
], function() {
Route::get('logout', 'AuthController@logout');
Route::get('user', 'AuthController@user');
});
});
¿Qué hace este código?
- Define 4 rutas, asignando a todas un prefijo "auth".
- Las 2 primeras rutas son públicas, y las 2 siguientes requieren de autenticación.
Paso 7: Crear un Controlador para resolver las rutas
En el paso anterior hemos declarado 4 rutas, cada una asociada con un método del controlador AuthController
.
Entonces sólo hace falta crear dicho controlador:
class AuthController extends Controller
{
/**
* Registro de usuario
*/
public function signUp(Request $request)
{
$request->validate([
'name' => 'required|string',
'email' => 'required|string|email|unique:users',
'password' => 'required|string'
]);
User::create([
'name' => $request->name,
'email' => $request->email,
'password' => bcrypt($request->password)
]);
return response()->json([
'message' => 'Successfully created user!'
], 201);
}
/**
* Inicio de sesión y creación de token
*/
public function login(Request $request)
{
$request->validate([
'email' => 'required|string|email',
'password' => 'required|string',
'remember_me' => 'boolean'
]);
$credentials = request(['email', 'password']);
if (!Auth::attempt($credentials))
return response()->json([
'message' => 'Unauthorized'
], 401);
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
if ($request->remember_me)
$token->expires_at = Carbon::now()->addWeeks(1);
$token->save();
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_at' => Carbon::parse($token->expires_at)->toDateTimeString()
]);
}
/**
* Cierre de sesión (anular el token)
*/
public function logout(Request $request)
{
$request->user()->token()->revoke();
return response()->json([
'message' => 'Successfully logged out'
]);
}
/**
* Obtener el objeto User como json
*/
public function user(Request $request)
{
return response()->json($request->user());
}
}
Paso 8: Verificar el funcionamiento de la API
Aquí puedes iniciar un servidor con PHP usando php artisan serve
.
Sin embargo, si dispones de un servidor web como Apache, lo mejor es que definas VirtualHosts para tus proyectos.
Para probar nuestra API debemos hacer peticiones a las rutas que hemos definido.
Una forma muy conveniente de hacerlo es a través de Postman.
¡Entonces empecemos!
Headers
Dado que estamos consultando una API Rest que devuelve datos en formato JSON, es importante agregar los siguientes 2 headers en cada una de nuestras peticiones:
Content-Type: application/json
X-Requested-With: XMLHttpRequest
Registro
Hacemos una petición POST y registramos un usuario con nuestros datos.
Login
Usando nuestros datos de usuario podemos iniciar sesión, y obtener un access_token
, que nos permitirá identificarnos ante la API.
Datos de usuario
Podemos consultar rutas protegidas enviando un Authorization
header y el token que obtuvimos anteriormente.
Cerrar sesión
Si hacemos una petición GET a la ruta de logout con nuestro token, éste será invalidado.
No autenticado
De modo que si intentamos obtener nuestros datos de usuario con el mismo token, la API protegida por el middleware nos responderá que no estamos autenticados.