Creación de una API Laravel segura con autenticación JWT
Cuando se construyen APIs con Laravel, garantizar una autenticación segura es crucial, especialmente cuando se trata de datos de usuario. Los JSON Web Tokens (JWT) ofrecen un método robusto para manejar la autenticación en aplicaciones sin estado, permitiendo la transmisión segura de información de usuario entre las partes. Esta guía le guiará a través del proceso de construcción de una API Laravel segura utilizando la autenticación JWT.
Requisitos previos
- Conocimientos básicos de PHP y Laravel.
- Laravel instalado en su máquina (preferiblemente Laravel 9 o más reciente).
- Composer instalado.
- MySQL u otra base de datos configurada para tu aplicación.
Paso 1: Crear un nuevo proyecto Laravel
Primero, crea un nuevo proyecto Laravel usando Composer:
composer create-project laravel/laravel laravel-jwt-api
Navega hasta el directorio de tu proyecto:
cd laravel-jwt-api
Paso 2: Instalar el paquete de autenticación JWT
El paquete más utilizado para la autenticación JWT en Laravel es tymon/jwt-auth. Instálalo usando Composer:
composer require tymon/jwt-auth
Tras la instalación del paquete, publica la configuración JWT:
php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider"
Esto creará un archivo config/jwt.php en tu proyecto.
Paso 3: Generar la clave secreta JWT
Generar una clave secreta que JWT utilizará para firmar tokens:
php artisan jwt:secret
Esto añadirá una entrada JWT_SECRET a su archivo .env, que se utiliza para codificar y decodificar los tokens.
Paso 4: Configurar la autenticación
Para configurar la autenticación JWT, necesita configurar la guardia por defecto para su API. Actualice el archivo config/auth. php como se indica a continuación:
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
Paso 5: Crear el modelo de usuario y la migración
Si aún no ha creado un modelo de Usuario, puede crearlo junto con su archivo de migración:
php artisan make:model Usuario -m
Abra el archivo de migración generado en database/migrations/ y añada los campos necesarios, como nombre, email y contraseña:
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->string('password');
$table->timestamps();
});
}
Ejecuta la migración para crear la tabla de usuarios:
php artisan migrate
Paso 6: Implementar métodos JWT en el modelo de usuario
En el modelo de Usuario(app/Models/User.php), implementa la interfaz JWTSubject y los métodos requeridos:
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable implements JWTSubject
{
public function getJWTIdentifier()
{
return $this->getKey(); // Usually the primary key (id)
}
public function getJWTCustomClaims()
{
return [];
}
}
Paso 7: Crear controladores de autenticación
Cree un controlador para gestionar la autenticación de usuarios:
php artisan make:controller AuthController
En AuthController.php, añade métodos para registrar un usuario, iniciar sesión y cerrar sesión:
<?php
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Tymon\JWTAuth\Facades\JWTAuth;
class AuthController extends Controller
{
// User Registration
public function register(Request $request)
{
$request->validate([
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
$user = User::create([
'name' => $request->name,
'email' => $request->email,
'password' => Hash::make($request->password),
]);
$token = JWTAuth::fromUser($user);
return response()->json(['token' => $token], 201);
}
// User Login
public function login(Request $request)
{
$credentials = $request->only('email', 'password');
if (!$token = Auth::attempt($credentials)) {
return response()->json(['error' => 'Invalid credentials'], 401);
}
return response()->json(['token' => $token]);
}
// Logout User (Invalidate Token)
public function logout()
{
Auth::logout();
return response()->json(['message' => 'Successfully logged out']);
}
// Get Authenticated User
public function me()
{
return response()->json(Auth::user());
}
}
Paso 8: Definir rutas API
Añadir rutas para la autenticación en routes/api.php:
use App\Http\Controllers\AuthController;
use Illuminate\Support\Facades\Route;
Route::post('register', [AuthController::class, 'register']);
Route::post('login', [AuthController::class, 'login']);
// Protected routes (require JWT token)
Route::middleware('auth:api')->group(function () {
Route::post('logout', [AuthController::class, 'logout']);
Route::get('me', [AuthController::class, 'me']);
});
Estas rutas gestionan el registro de usuarios, el inicio de sesión, el cierre de sesión y la obtención del usuario autenticado.
Paso 9: Proteger las rutas API
Para proteger otras rutas API, puede utilizar el middleware auth:api. Por ejemplo, si tiene una ruta de recursos para entradas:
Route::middleware('auth:api')->group(function () {
Route::resource('posts', PostController::class);
});
Esto asegura que sólo los usuarios autenticados pueden acceder a estas rutas.
Paso 10: Probar la API
Puede probar su API utilizando herramientas como Postman o cURL.
- Registre un usuario:
POST /api/register
Host: your-domain.com
Content-Type: application/json
{
"name": "John Doe",
"email": "john@example.com",
"password": "password",
"password_confirmation": "password"
} - Iniciar sesión:
POST /api/login
Host: your-domain.com
Content-Type: application/json
{
"email": "john@example.com",
"password": "password"
}Esto devolverá un token que podrás utilizar para autenticar otras peticiones. - Acceder a una ruta protegida:Para acceder a una ruta protegida como GET /api/me, incluye el token en la cabecera Authorization:
Authorization: Bearer <token>
Paso 11: Actualización de tokens JWT (opcional)
Para refrescar un token, puedes añadir un método en AuthController:
public function refresh()
{
$token = Auth::refresh();
return response()->json(['token' => $token]);
}
Añade la ruta para refrescar:
Route::post('refresh', [AuthController::class, 'refresh'])->middleware('auth:api');
Conclusión
Siguiendo esta guía, has construido una API Laravel segura con autenticación JWT, permitiendo el registro de usuarios, login y acceso a rutas protegidas. JWT te permite mantener un mecanismo de autenticación sin estado, lo que es especialmente útil para escalar APIs. Con esta configuración, puedes personalizar aún más la lógica de autenticación de tu aplicación e integrar características adicionales, como el control de acceso basado en roles y tokens de actualización para sesiones de larga duración.