Generar un JSON Web Token (JWT) en Laravel es una tarea fundamental si deseas manejar autenticación o comunicación segura entre servicios. Hoy te explicaré cómo hacerlo utilizando el algoritmo RS256 (que emplea claves RSA) y añadiendo claims personalizados. Vamos paso a paso para que puedas implementarlo sin complicaciones. 🚀
Un JWT es un estándar para transmitir información de manera segura entre partes como un objeto JSON firmado digitalmente. Usar RS256 (un algoritmo asimétrico) aporta seguridad adicional, ya que involucra un par de claves: una privada para firmar el token y otra pública para verificarlo. Este enfoque es ideal en aplicaciones que requieren un alto nivel de seguridad.
Para comenzar, necesitamos un par de claves RSA: una privada y una pública.
En tu terminal, ejecuta los siguientes comandos para generar las claves:
openssl genrsa -out private.key 2048
openssl rsa -in private.key -pubout -out public.key
Esto generará dos archivos:
Guarda estas claves en una ubicación segura, como storage/app/keys
. Asegúrate de establecer los permisos adecuados:
chmod 600 storage/app/keys/private.key
chmod 644 storage/app/keys/public.key
Esto garantiza que solo el propietario pueda acceder a la clave privada. 🔒
Para generar y manejar JWTs, utilizaremos la librería lcobucci/jwt, ampliamente utilizada en PHP.
Ejecuta el siguiente comando para instalarla mediante Composer:
composer require lcobucci/jwt
Esta librería ofrece una API robusta para construir, firmar y validar tokens.
Vamos a implementar la lógica para generar JWTs dentro de un servicio dedicado. Crea un archivo llamado JwtService.php
en el directorio app/Services/
con el siguiente contenido:
<?php
namespace App\Services;
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Configuration;
use Lcobucci\JWT\Signer\Rsa\Sha256;
use Lcobucci\JWT\Signer\Key\InMemory;
class JwtService
{
private $config;
public function __construct()
{
// Configurar el firmador y las claves
$this->config = Configuration::forAsymmetricSigner(
new Sha256(),
InMemory::file(storage_path('app/keys/private.key')), // Clave privada
InMemory::file(storage_path('app/keys/public.key')) // Clave pública
);
}
public function generateToken(array $customClaims): string
{
$now = new \DateTimeImmutable();
$builder = $this->config->builder()
->issuedBy('https://your-app.example.com') // Emisor del token
->permittedFor('https://your-client.example.com') // Audiencia
->identifiedBy('4f1g23a12aa', true) // ID único del token
->issuedAt($now) // Tiempo de emisión
->canOnlyBeUsedAfter($now) // Tiempo mínimo para usar
->expiresAt($now->modify('+1 hour')); // Tiempo de expiración
// Agregar claims personalizados
foreach ($customClaims as $key => $value) {
$builder->withClaim($key, $value);
}
// Construir y firmar el token
$token = $builder->getToken($this->config->signer(), $this->config->signingKey());
return $token->toString();
}
}
Ahora que tenemos nuestro servicio, utilicémoslo para generar un token. En un controlador, puedes hacer algo como esto:
use App\Services\JwtService;
$jwtService = new JwtService();
$customClaims = [
'user_id' => 123,
'role' => 'admin',
'permissions' => ['create', 'read', 'update', 'delete']
];
$token = $jwtService->generateToken($customClaims);
return response()->json(['token' => $token]);
Esto generará un JWT firmado con los claims personalizados que especifiques. 🌟
Si necesitas validar un token, puedes usar el mismo servicio. Aquí tienes un ejemplo:
use Lcobucci\JWT\Configuration;
$jwtService = new JwtService();
$config = $jwtService->getConfig(); // Obtén la configuración de JWT
$token = $config->parser()->parse($jwtTokenString);
if ($config->validator()->validate($token, ...)) {
// Token válido, puedes extraer los claims
$claims = $token->claims()->all();
}
Esto asegura que el token sea válido y no haya sido modificado.
Siguiendo estos pasos, puedes implementar JWT con el algoritmo RS256 en Laravel de manera segura y eficiente. Este enfoque es ideal para sistemas que requieren una autenticación robusta y escalable.
Jorge García
Fullstack developer