OAuth-Client für Rust: Bibliothek oauth2-rs

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Bibliothek oauth2-rs: Implementierung von OAuth 2.0 in Rust

\n\n

In der modernen Webentwicklung ist OAuth 2.0 das Standardprotokoll für die Delegierung des Zugriffs. Die Bibliothek oauth2-rs bietet eine vollständige Implementierung eines OAuth 2.0-Clients in der Sprache Rust. Sie ermöglicht die Integration der Authentifizierung über beliebte Dienste: Google, GitHub, Yandex, VK und andere.

\n\n

Diese Bibliothek unterstützt alle wichtigen Grants (Flows): Authorization Code, Client Credentials, Implicit sowie Refresh Token. Besonderes Augenmerk liegt auf der Sicherheit: Es wird PKCE (Proof Key for Code Exchange) für öffentliche Clients und eine obligatorische Token-Validierung verwendet.

\n\n

Installation von oauth2-rs

\n\n

Fügen Sie die Abhängigkeit in Cargo.toml hinzu:

\n\n
[dependencies]\noauth2 = "4.4"\ntokio = { version = "1", features = ["full"] }\nreqwest = { version = "0.11", features = ["json"] }\nserde = { version = "1.0", features = ["derive"] }
\n\n

Außerdem wird ein HTTP-Client (empfohlen wird reqwest mit Async-Unterstützung) und der Serialisierer serde für die Arbeit mit JSON benötigt.

\n\n

Grundlegende Konfiguration des OAuth-Clients

\n\n

Betrachten wir ein Beispiel für Google OAuth 2.0. Zuerst erstellen wir eine Konfiguration:

\n\n
use oauth2::{\n    AuthorizationCode, AuthUrl, ClientId, ClientSecret, \n    RedirectUrl, TokenUrl, CsrfToken, Scope,\n    basic::BasicClient, TokenResponse\n};\n\nlet client_id = ClientId::new("YOUR_GOOGLE_CLIENT_ID".to_string());\nlet client_secret = ClientSecret::new("YOUR_GOOGLE_CLIENT_SECRET".to_string());\nlet auth_url = AuthUrl::new("https://accounts.google.com/o/oauth2/v2/auth".to_string())\n    .expect("Invalid auth URL");\nlet token_url = TokenUrl::new("https://oauth2.googleapis.com/token".to_string())\n    .expect("Invalid token URL");\n\nlet client = BasicClient::new(\n    client_id,\n    Some(client_secret),\n    auth_url,\n    Some(token_url)\n).set_redirect_uri(\n    RedirectUrl::new("http://localhost:8080/callback".to_string())\n        .expect("Invalid redirect URL")\n);
\n\n

Generierung der URL für die Autorisierung

\n\n

Erstellen wir einen Link, zu dem der Benutzer weitergeleitet werden soll:

\n\n
let (auth_url, csrf_token) = client\n    .authorize_url(CsrfToken::new_random)\n    .add_scope(Scope::new("openid".to_string()))\n    .add_scope(Scope::new("email".to_string()))\n    .url();\n\nprintln!("Gehen Sie zu folgendem Link: {}", auth_url);\n// Speichern Sie csrf_token zur Überprüfung beim Callback
\n\n

CsrfToken schützt vor Cross-Site-Request-Forgery-Angriffen (CSRF). Es muss vorübergehend gespeichert (z. B. in der Session oder in Cookies) und bei der Verarbeitung des Callbacks überprüft werden.

\n\n

Verarbeitung des Callbacks und Abrufen des Tokens

\n\n

Nachdem der Benutzer den Zugriff bestätigt hat, leitet der Dienst ihn an die redirect_uri mit dem Parameter code weiter. Beispiel für einen Handler in Rust:

\n\n
use actix_web::{web, HttpRequest, HttpResponse};\nuse oauth2::AuthorizationCode;\n\nasync fn callback(query: web::Query<std::collections::HashMap<String, String>>) -> HttpResponse {\n    let code = query.get("code")\n        .expect("Fehlender Autorisierungscode");\n    let state = query.get("state")\n        .expect("Fehlender State");\n\n    // Überprüfen des state gegen den gespeicherten csrf_token\n    // ...\n\n    let token_result = client\n        .exchange_code(AuthorizationCode::new(code.clone()))\n        .request_async(&reqwest::Client::new())\n        .await;\n\n    match token_result {\n        Ok(token) => {\n            let access_token = token.access_token().secret();\n            let refresh_token = token.refresh_token()\n                .map(|rt| rt.secret().clone());\n            // Speichern der Tokens in der DB oder Session\n            HttpResponse::Ok().body("Autorisierung erfolgreich!")\n        },\n        Err(e) => {\n            eprintln!("Fehler beim Austausch des Codes: {:?}", e);\n            HttpResponse::InternalServer                    

Empfehlungen