Introducción: ¿por qué es necesaria la autorización en Rust?
Las aplicaciones web modernas rara vez prescinden de un sistema de autenticación y autorización. Rust, gracias a su rendimiento y seguridad de memoria, se está convirtiendo en una opción popular para crear servicios de alta carga. Sin embargo, trabajar con protocolos como OAuth 2.0 y el formato JWT puede parecer complejo para los principiantes.
En este artículo, analizaremos los conceptos básicos de OAuth 2.0 y JWT (JSON Web Token) e implementaremos un sistema de autorización simple en Rust utilizando crates populares. Aprenderá cómo proteger sus endpoints de API y trabajar con tokens de acceso.
¿Qué son OAuth 2.0 y JWT?
Antes de escribir código, es importante entender la teoría.
OAuth 2.0: protocolo de acceso delegado
OAuth 2.0 es un protocolo que permite a una aplicación obtener acceso limitado a los recursos de un usuario sin transferir su nombre de usuario y contraseña. Imagine que quiere iniciar sesión en un sitio web a través de Google o GitHub; eso es OAuth 2.0.
Participantes principales del protocolo:
- Resource Owner — el usuario propietario de los datos.
- Client — su aplicación en Rust que desea obtener acceso.
- Authorization Server — el servidor que emite tokens (por ejemplo, Google).
- Resource Server — la API que proporciona los datos (por ejemplo, Google Drive).
JWT: formato de token compacto
JWT (JSON Web Token) es un estándar abierto para crear tokens de acceso. El token consta de tres partes separadas por puntos:
- Header — tipo de token y algoritmo de firma.
- Payload — datos (claims), por ejemplo, ID de usuario o rol.
- Signature — firma que garantiza que el token no ha sido modificado.
Ejemplo de JWT: eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNrxP0G7n9G4W7N8Y7J8
JWT es conveniente porque no requiere almacenar sesiones en el servidor; toda la información ya está codificada en el token.
Configuración del proyecto Rust para autorización
Usaremos el framework Actix Web y varios crates auxiliares. Cree un nuevo proyecto:
cargo new rust-auth-examplecd rust-auth-exampleAgregue las dependencias en Cargo.toml:
[dependencies]actix-web = "4"actix-rt = "2"serde = { version = "1", features = ["derive"] }serde_json = "1"jsonwebtoken = "9"chrono = { version = "0.4", features = ["serde"] }dotenv = "0.15"env_logger = "0.10"bcrypt = "0.15"Estructura de archivos
Para mayor comodidad, crearemos una estructura modular:
src/├── main.rs├── auth.rs├── models.rs└── handlers.rsEn .env escribiremos la clave secreta para JWT:
JWT_SECRET=supersecretkey12345DATABASE_URL=sqlite://users.dbImplementación de JWT en Rust: desde la generación hasta la verificación
Empecemos con el módulo auth.rs, que se encargará del trabajo con JWT.
Estructuras para JWT
// auth.rsuse serde::{Deserialize, Serialize};use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};use chrono::{Utc, Duration};
#[derive(Debug, Serialize, Deserialize)]pub struct Claims { pub sub: String, // ID de usuario pub exp: usize, // tiempo de expiración pub iat: usize, // tiempo de emisión}
pub fn create_jwt(user_id: &str, secret: &str) -> Result<String, jsonwebtoken::errors::Error> { let now = Utc::now(); let expiration = now + Duration::hours(24); // el token vive 24 horas
let claims = Claims { sub: user_id.to_owned(), exp: expiration.timestamp() as usize, iat: now.timestamp() as usize, };
let token = encode( &Header::default(), &claims,\