Autorización y autenticación en Rust: revisión completa de herramientas
Rust es un lenguaje de programación de sistemas que se utiliza cada vez más para crear servicios web de alta carga. Los problemas de seguridad, incluida la autenticación (verificación de la identidad del usuario) y la autorización (verificación de permisos de acceso), son especialmente críticos aquí. En este artículo, analizaremos las bibliotecas y enfoques clave para implementar estos mecanismos en el ecosistema de Rust.
Enfoques principales para la autenticación
En los proyectos de Rust, se utilizan con mayor frecuencia tres estrategias:
- Autenticación por sesión — el servidor almacena el estado de la sesión (generalmente en Redis o memoria), el cliente recibe una cookie con el identificador de sesión.
- JWT (JSON Web Token) — tokens sin estado que contienen afirmaciones (claims) y son firmados por el servidor.
- OAuth2 / OpenID Connect — autenticación descentralizada a través de proveedores externos (Google, GitHub, Yandex).
Bibliotecas clave de Rust
1. jsonwebtoken — trabajo con JWT
La biblioteca más popular para crear y verificar tokens JWT. Admite HS256, RS256, ES256 y otros algoritmos.
use jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};
// Creación del tokenlet claims = serde_json::json!({ "sub": "user123", "exp": 1740000000, "role": "admin"});let token = encode(&Header::default(), &claims, &EncodingKey::from_secret("secret".as_ref())).unwrap();
// Verificaciónlet token_data = decode::<serde_json::Value>( &token, &DecodingKey::from_secret("secret".as_ref()), &Validation::default()).unwrap();println!("El token pertenece a: {}", token_data.claims["sub"]);2. bcrypt — hash de contraseñas
Hash seguro con sal. Se utiliza para almacenar contraseñas de forma segura en la base de datos.
use bcrypt::{hash, verify, DEFAULT_COST};
let password = "super_secret_123";let hashed = hash(password, DEFAULT_COST).unwrap();println!("Hash: {}", hashed);
let valid = verify(password, &hashed).unwrap();println!("Contraseña válida: {}", valid); // true3. actix-web-identity / actix-web-flash — sesiones para Actix Web
Si usas el framework Actix Web, estos crates te ayudarán a gestionar sesiones mediante cookies o Redis.
use actix_web::{web, App, HttpServer, HttpRequest, HttpResponse, middleware::IdentityService};use actix_web::cookie::Key;
async fn login(req: HttpRequest) -> HttpResponse { let identity = req.extensions().get::<Identity>().unwrap(); identity.remember("user_id=42".to_string()); HttpResponse::Ok().body("Autorizado")}
#[actix_web::main]async fn main() -> std::io::Result<()> { HttpServer::new(|| { App::new() .wrap(IdentityService::new(Key::from(&[0; 32]))) .route("/login", web::get().to(login)) }) .bind("127.0.0.1:8080")? .run() .await}4. oauth2 — cliente OAuth2
Biblioteca para implementar flujos OAuth2 (por ejemplo, "Iniciar sesión con GitHub"). Admite Authorization Code, Client Credentials y Refresh Token.
use oauth2::{basic::BasicClient, AuthUrl, TokenUrl, ClientId, ClientSecret, RedirectUrl};
let client = BasicClient::new( ClientId::new("your_client_id".to_string()), Some(ClientSecret::new("your_client_secret".to_string())), AuthUrl::new("https://github.com/login/oauth/authorize".to_string()).unwrap(), Some(TokenUrl::new("https://github.com/login/oauth/access_token".to_string()).unwrap())).set_redirect_uri(RedirectUrl::new("http://localhost:8080/callback".to_string()).unwrap());Comparación de enfoques
- JWT — la mejor opción para microservicios y API, no requiere servidor