Autorisation et authentification en Rust : de JWT aux sessions
Dans le monde de la programmation système et web, Rust a acquis une réputation de langage sûr et rapide. Cependant, lors de la création d'applications web, les développeurs sont souvent confrontés à la tâche de mise en œuvre de l'authentification (vérification de l'identité de l'utilisateur) et de l'autorisation (vérification des droits d'accès). Dans cet article, nous examinerons les bibliothèques et approches clés pour implémenter ces mécanismes en Rust, et fournirons des exemples de code pratiques.
Concepts fondamentaux de l'authentification et de l'autorisation
Avant de passer aux outils, il est important de distinguer les concepts :
- Authentification — le processus de vérification que l'utilisateur est bien celui qu'il prétend être. Généralement effectué via un identifiant/mot de passe, des jetons ou la biométrie.
- Autorisation — la détermination des ressources et actions accessibles à un utilisateur authentifié. Souvent implémentée via des rôles (administrateur, modérateur, utilisateur) ou des droits d'accès.
En Rust, les deux processus peuvent être implémentés à la fois à bas niveau (gestion manuelle des jetons) et à l'aide de bibliothèques prêtes à l'emploi.
Bibliothèques populaires pour l'authentification en Rust
Pour travailler avec les sessions et les jetons en Rust, il existe plusieurs solutions matures :
actix-identity— pour la gestion des sessions dans le framework web Actix-web. Prend en charge les sessions par cookie et Redis.jsonwebtoken— bibliothèque pour travailler avec JWT (JSON Web Tokens). Permet de créer, signer et vérifier des jetons.argon2— implémentation de l'algorithme de hachage de mots de passe Argon2, recommandé par l'OWASP.bcrypt— bibliothèque classique pour le hachage de mots de passe.
Ci-dessous, nous examinons chaque outil avec un exemple.
Exemple 1 : Authentification avec JWT et jsonwebtoken
JWT est l'une des méthodes d'authentification les plus populaires dans les API REST. Le jeton contient des revendications (claims) et est signé avec une clé secrète. Examinons une implémentation de base avec la bibliothèque jsonwebtoken.
// cargo add jsonwebtoken serdeuse jsonwebtoken::{encode, decode, Header, Validation, EncodingKey, DecodingKey};use serde::{Serialize, Deserialize};
#[derive(Debug, Serialize, Deserialize)]struct Claims { sub: String, // identifiant utilisateur exp: usize, // date d'expiration (timestamp UNIX) role: String, // rôle de l'utilisateur}
fn create_token(user_id: &str, role: &str) -> Result<String, jsonwebtoken::errors::Error> { let claims = Claims { sub: user_id.to_owned(), exp: (chrono::Utc::now() + chrono::Duration::hours(24)).timestamp() as usize, role: role.to_owned(), }; encode( &Header::default(), &claims, &EncodingKey::from_secret(b"votre_clé_secrète") )}
fn verify_token(token: &str) -> Result<Claims, jsonwebtoken::errors::Error> { let token_data = decode::<Claims>( token, &DecodingKey::from_secret(b"votre_clé_secrète"), &Validation::default() )?; Ok(token_data.claims)}Dans cet exemple, nous créons un jeton valable 24 heures contenant l'ID de l'utilisateur et son rôle. La fonction verify_token vérifie la signature et retourne les revendications (claims) qui peuvent être utilisées pour l'autorisation.
Exemple 2 : Hachage de mots de passe avec Argon2
Ne stockez jamais les mots de passe en clair ! Utilisez Argon2 — un algorithme de hachage moderne et sécurisé.
// cargo add argon2use argon2::{Argon2, PasswordHash, PasswordHasher, PasswordVerifier};use argon2::password_hash::{SaltString, rand_core::OsRng};
fn hash_password(password: &str) -> String { let salt = SaltString::generate(&mut OsRng); let argon2 = Argon2::default(); argon2.hash_password(password.as_bytes(), &salt) .expect("Erreur de hachage")