Introduction : pourquoi l'autorisation en Rust ?
Les applications web modernes se passent rarement d'un système d'authentification et d'autorisation. Rust, grâce à ses performances et sa sécurité mémoire, devient un choix populaire pour créer des services à forte charge. Cependant, travailler avec des protocoles comme OAuth 2.0 et le format JWT peut sembler complexe pour les débutants.
Dans cet article, nous allons détailler les concepts de base d'OAuth 2.0 et JWT (JSON Web Token) et implémenter un système d'autorisation simple en Rust en utilisant des crates populaires. Vous apprendrez à sécuriser vos points de terminaison API et à travailler avec des jetons d'accès.
Qu'est-ce que OAuth 2.0 et JWT ?
Avant d'écrire du code, il est important de comprendre la théorie.
OAuth 2.0 : protocole d'accès délégué
OAuth 2.0 est un protocole qui permet à une application d'obtenir un accès limité aux ressources d'un utilisateur sans transmettre son identifiant et son mot de passe. Imaginez que vous souhaitiez vous connecter à un site via Google ou GitHub — c'est cela OAuth 2.0.
Les principaux acteurs du protocole :
- Resource Owner — l'utilisateur propriétaire des données.
- Client — votre application en Rust qui souhaite obtenir l'accès.
- Authorization Server — le serveur qui délivre les jetons (par exemple, Google).
- Resource Server — l'API qui fournit les données (par exemple, Google Drive).
JWT : format de jeton compact
JWT (JSON Web Token) est un standard ouvert pour créer des jetons d'accès. Le jeton se compose de trois parties séparées par des points :
- Header — le type de jeton et l'algorithme de signature.
- Payload — les données (claims), par exemple, l'ID utilisateur ou le rôle.
- Signature — la signature qui garantit que le jeton n'a pas été modifié.
Exemple de JWT : eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozjgNrxP0G7n9G4W7N8Y7J8
JWT est pratique car il ne nécessite pas de stockage de sessions sur le serveur — toutes les informations sont déjà intégrées dans le jeton.
Configuration du projet Rust pour l'autorisation
Nous allons utiliser le framework Actix Web et plusieurs crates auxiliaires. Créez un nouveau projet :
cargo new rust-auth-examplecd rust-auth-exampleAjoutez les dépendances dans 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"Structure des fichiers
Pour plus de clarté, créons une structure modulaire :
src/├── main.rs├── auth.rs├── models.rs└── handlers.rsDans .env, nous définissons la clé secrète pour JWT :
JWT_SECRET=supersecretkey12345DATABASE_URL=sqlite://users.dbImplémentation de JWT en Rust : de la génération à la vérification
Commençons par le module auth.rs, qui sera responsable de la gestion des JWT.
Structures pour 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 utilisateur pub exp: usize, // date d'expiration pub iat: usize, // date d'émission}
pub fn create_jwt(user_id: &str, secret: &str) -> Result<String, jsonwebtoken::errors::Error> { let now = Utc::now(); let expiration = now + Duration::hours(24); // le jeton vit 24 heures
let claims = Claims { sub: user_id.to_owned(), exp: expiration.timestamp() as usize, iat: now.timestamp() as usize, };
let token = encode( &Header::default(), &claims,\