Autenticación segura en Rust: escribiendo un backend protegido

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

¿Por qué Rust es la elección ideal para la autenticación?

\n\n

Si estás escribiendo una aplicación web en Rust, ya estás un paso adelante en seguridad. Rust no perdona errores de memoria, lo que significa que muchas vulnerabilidades (desbordamiento de búfer, use-after-free) se eliminan en la etapa de compilación. Pero el compilador no te protegerá de una mala lógica de autenticación. De eso se trata este artículo: cómo construir autenticación segura en Rust utilizando prácticas modernas.

\n\n

En este artículo, montaremos un módulo de autenticación completo: hash de contraseñas con bcrypt, emisión de tokens JWT, verificación middleware en Actix-web y protección contra ataques típicos. El código será funcional: puedes usarlo directamente en tu proyecto.

\n\n

1. Hash de contraseñas: ¿por qué bcrypt y no SHA-256?

\n\n

Muchos principiantes piensan: "Usaré SHA-256, es rápido y confiable". Y ese es un error fatal. SHA es una función hash criptográfica, pero es demasiado rápida. Un atacante puede probar miles de millones de combinaciones por segundo. Necesitamos una función lenta, diseñada específicamente para contraseñas.

\n\n

bcrypt es el estándar de oro. Incluye "sal" (salt) y un "factor de costo" (cost factor) que se puede aumentar a medida que crece la potencia computacional.

\n\n

Añadiendo bcrypt a Cargo.toml

\n
[dependencies]\nbcrypt = "0.15"
\n\n

Hasheando la contraseña

\n
use bcrypt::{hash, verify, DEFAULT_COST};\n\nfn hash_password(plain: &str) -> Result<String, bcrypt::BcryptError> {\n    hash(plain, DEFAULT_COST) // cost = 12 (por defecto)\n}\n\nfn verify_password(plain: &str, hashed: &str) -> bool {\n    verify(plain, hashed).unwrap_or(false)\n}
\n\n

Observa: verify extrae la sal del hash por sí mismo. No necesitas almacenar la sal por separado, ya está dentro de la cadena del hash. Esto es seguro y conveniente.

\n\n

2. Tokens JWT: cómo no fallar en la autenticación

\n\n

Después de que el usuario ingresa su contraseña, debemos emitirle un "pase". JWT (JSON Web Token) es un formato compacto y autónomo. Pero el diablo está en los detalles:

\n\n
    \n
  • No almacenes la clave secreta en el código. Usa variables de entorno.
  • \n
  • Establece una vida útil corta. Token de acceso: 15–30 minutos, token de actualización: 7–30 días.
  • \n
  • No insertes datos sensibles en el payload. Solo el ID del usuario y el rol.
  • \n
\n\n

Implementación de JWT con jsonwebtoken

\n\n
use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};\nuse serde::{Serialize, Deserialize};\nuse chrono::{Utc, Duration};\n\n#[derive(Debug, Serialize, Deserialize)]\npub struct Claims {\n    pub sub: String,       // ID del usuario\n    pub exp: usize,        // timestamp de expiración\n    pub iat: usize,        // emitido en\n}\n\npub fn create_token(user_id: &str, secret: &str) -> Result<String, jsonwebtoken::errors::Error> {\n    let now = Utc::now();\n    let claims = Claims {\n        sub: user_id.to_owned(),\n        exp: (now + Duration::minutes(30)).timestamp() as usize,\n        iat: now.timestamp() as usize,\n    };\n    encode(&Header::default(), &claims, &EncodingKey::from_secret(secret.as_bytes()))\n}\n\npub fn validate_token(token: &str, secret: &str) -> Result<Claims, jsonwebtoken::errors::Error> {\n    let token_data = decode::<Claims>(\n        token,\n        &DecodingKey::from_secret(secret.as_bytes()),\n        &Validation::default(),\n    )?;\n    Ok(token_data.claims)\n}
\n\n

3. Uniendo todo: Actix-web + middleware

\n\n

Ahora conectemos el hash y JWT en una aplicación web completa con Actix-web. Escribiremos un middleware que verifique el token en cada solicitud protegida.

\n\n

Estructura del proyecto

\n
src/\n├── main.rs\n├── auth.rs       # hash, JWT\n├── middleware.rs # verificación de token\n└── handlers.rs   #                

Blogs

Book Recommendations