Client OAuth pour Rust : bibliothèque oauth2
OAuth 2.0 est la norme industrielle pour la délégation d'accès. Il est largement utilisé pour autoriser les utilisateurs via des services tiers (Google, GitHub, Facebook) sans transmettre de mot de passe. Dans l'écosystème Rust, l'une des bibliothèques les plus populaires et matures pour implémenter OAuth 2.0 est oauth2 (crate oauth2). Elle fournit une API sécurisée, asynchrone et flexible pour travailler avec n'importe quel fournisseur OAuth.
Fonctionnalités principales
- Prise en charge de toutes les subventions standard : Authorization Code, Client Credentials, Resource Owner Password Credentials, Implicit.
- Prise en charge intégrée de PKCE (Proof Key for Code Exchange) pour améliorer la sécurité des clients publics.
- Fonctionnement asynchrone utilisant
reqwestouureqen interne. - Sécurité de type : tous les jetons, URL et paramètres sont strictement typés, éliminant les erreurs à la compilation.
- Configuration flexible pour tout fournisseur via la configuration des points de terminaison et des scopes.
- Gestion des jetons : renouvellement automatique (refresh), vérification de l'expiration.
Installation
Ajoutez la dépendance à votre Cargo.toml :
[dependencies]oauth2 = "4.4"tokio = { version = "1", features = ["full"] }serde = { version = "1", features = ["derive"] }reqwest = { version = "0.11", features = ["json"] }Exemple de base : autorisation via Google
Examinons le cycle complet d'OAuth 2.0 avec la subvention Authorization Code + PKCE pour Google :
use oauth2::{ AuthorizationCode, AuthUrl, ClientId, ClientSecret, CsrfToken, PkceCodeChallenge, RedirectUrl, Scope, TokenResponse, TokenUrl,};use oauth2::basic::BasicClient;use oauth2::reqwest::async_http_client;use url::Url;
#[tokio::main]async fn main() -> Result<(), Box> { // 1. Création du client avec les paramètres de Google let client = BasicClient::new( ClientId::new("VOTRE_GOOGLE_CLIENT_ID".to_string()), Some(ClientSecret::new("VOTRE_GOOGLE_CLIENT_SECRET".to_string())), AuthUrl::new("https://accounts.google.com/o/oauth2/v2/auth".to_string())?, Some(TokenUrl::new("https://oauth2.googleapis.com/token".to_string())?), ) .set_redirect_uri(RedirectUrl::new("http://localhost:8080/callback".to_string())?);
// 2. Génération du challenge PKCE let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256();
// 3. Construction de l'URL d'autorisation pour l'utilisateur let (auth_url, csrf_token) = client .authorize_url(CsrfToken::new_random) .add_scope(Scope::new("openid".to_string())) .add_scope(Scope::new("profile".to_string())) .add_scope(Scope::new("email".to_string())) .set_pkce_challenge(pkce_challenge) .url();
println!("Ouvrez dans le navigateur : {}", auth_url);
// 4. (Simulation) récupération du code d'autorisation de l'utilisateur let code = "code_du_navigateur_après_redirection";
// 5. Échange du code contre un jeton let token_response = client .exchange_code(AuthorizationCode::new(code.to_string())) .set_pkce_verifier(pkce_verifier) .request_async(async_http_client) .await?;
println!("Access token : {}", token_response.access_token().secret()); println!("Refresh token : {:?}", token_response.refresh_token());
Ok(())} Scénarios avancés
1. Renouvellement du jeton (Refresh Token)
Lorsque le jeton d'accès expire, utilisez le refresh token pour en obtenir un nouveau :
use oauth2::RefreshToken;
let refresh_token = RefreshToken::new("votre_refresh_token".to_string());let new_token = client .exchange_refresh_token(&refresh_token) .requ