Tokens JWT en Rust: librería jsonwebtoken y trabajo con autenticación

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Tokens JWT en Rust: librería jsonwebtoken

JSON Web Tokens (JWT) es un estándar abierto (RFC 7519) para la creación de tokens de acceso basados en JSON. En el ecosistema de Rust, una de las librerías más populares y estables para trabajar con JWT es jsonwebtoken. Proporciona un conjunto completo de funciones para crear, firmar, verificar y decodificar tokens JWT, soportando tanto algoritmos de cifrado simétricos (HS256, HS384, HS512) como asimétricos (RS256, RS384, RS512, ES256, ES384).



Instalación y configuración

Para comenzar, agregue la dependencia en el archivo Cargo.toml de su proyecto:

[dependencies]jsonwebtoken = "9.3"serde = { version = "1.0", features = ["derive"] }chrono = "0.4"

La librería serde es necesaria para la serialización y deserialización de los datos del token, y chrono simplifica el trabajo con marcas de tiempo (exp, iat, nbf).



Estructura básica de JWT

Un token JWT consta de tres partes: encabezado (header), carga útil (claims) y firma. En Rust, esto se implementa mediante estructuras:

use serde::{Serialize, Deserialize};

#[derive(Debug, Serialize, Deserialize)]struct Claims { sub: String, // sujeto (generalmente ID de usuario) exp: usize, // tiempo de expiración (timestamp Unix) iat: usize, // tiempo de creación (timestamp Unix) role: String, // campo personalizado}


Creación y firma de un token JWT

Veamos un ejemplo completo de creación de un token utilizando el algoritmo HS256 (cifrado simétrico):

use jsonwebtoken::{encode, Header, EncodingKey};use chrono::Utc;

fn create_jwt(user_id: &str, secret: &str) -> Result { let now = Utc::now().timestamp() as usize; let claims = Claims { sub: user_id.to_string(), exp: now + 3600, // el token es válido por 1 hora iat: now, role: "user".to_string(), };

let token = encode( &Header::default(), // por defecto HS256 &claims, &EncodingKey::from_secret(secret.as_bytes()), )?; Ok(token)}


Verificación y decodificación del token

Para verificar la autenticidad del token se utiliza la función decode especificando el algoritmo y la clave secreta:

use jsonwebtoken::{decode, DecodingKey, Validation, Algorithm};

fn verify_jwt(token: &str, secret: &str) -> Result { let validation = Validation::new(Algorithm::HS256); let token_data = decode::( token, &DecodingKey::from_secret(secret.as_bytes()), &validation, )?; Ok(token_data.claims)}


Trabajo con algoritmos asimétricos (RS256)

Para entornos de producción se recomienda utilizar cifrado asimétrico. Ejemplo con RS256:

use jsonwebtoken::{encode, decode, Header, EncodingKey, DecodingKey, Validation, Algorithm};

// Creación de token con clave privadafn create_rs256_token(user_id: &str, private_key_pem: &str) -> Result> { let claims = Claims { sub: user_id.to_string(), exp: (Utc::now().timestamp() + 3600) as usize, iat: Utc::now().timestamp() as usize, role: "admin".to_string(), };

let token = encode( &Header::new(Algorithm::RS256), &claims, &EncodingKey::from_rsa_pem(private_key_pem.as_bytes())?, )?; Ok(token)}

// Verificación con clave públicafn verify_rs256_token(token: &str, public_key_pem: &str) -> Result> { let mut validation = Validation::new(Algorithm::RS256); validation.validate_exp = true; // verificar fecha de expiración

let token_data = decode::( token, &DecodingKey::from_rsa_pem(public_key_pem.as_bytes())?, &validat

Recommendations