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 También en la biblioteca
Caché en Swift (iOS/macOS): Redis, NSCache y Core Data
Envío de email en C# (.NET) usando SmtpClient y MailKit
Trabajo con Excel en Kotlin: bibliotecas Apache POI y envoltorios de Kotlin