OAuth client for Rust: oauth2-rs library

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

oauth2-rs library: OAuth 2.0 implementation in Rust



In modern web development, OAuth 2.0 is the standard protocol for delegated access. The oauth2-rs library provides a complete OAuth 2.0 client implementation in Rust. It allows integrating authentication through popular services: Google, GitHub, Yandex, VK, and others.



This library supports all key grants (flows): Authorization Code, Client Credentials, Implicit, and Refresh Token. Special attention is paid to security: PKCE (Proof Key for Code Exchange) is used for public clients, along with mandatory token validation.



Installing oauth2-rs



Add the dependency to Cargo.toml:



[dependencies]oauth2 = "4.4"tokio = { version = "1", features = ["full"] }reqwest = { version = "0.11", features = ["json"] }serde = { version = "1.0", features = ["derive"] }


You will also need an HTTP client (reqwest with async support is recommended) and the serde serializer for working with JSON.



Basic OAuth client setup



Let's look at an example for Google OAuth 2.0. First, create the configuration:



use oauth2::{    AuthorizationCode, AuthUrl, ClientId, ClientSecret,     RedirectUrl, TokenUrl, CsrfToken, Scope,    basic::BasicClient, TokenResponse};

let client_id = ClientId::new("YOUR_GOOGLE_CLIENT_ID".to_string());let client_secret = ClientSecret::new("YOUR_GOOGLE_CLIENT_SECRET".to_string());let auth_url = AuthUrl::new("https://accounts.google.com/o/oauth2/v2/auth".to_string()) .expect("Invalid auth URL");let token_url = TokenUrl::new("https://oauth2.googleapis.com/token".to_string()) .expect("Invalid token URL");

let client = BasicClient::new( client_id, Some(client_secret), auth_url, Some(token_url)).set_redirect_uri( RedirectUrl::new("http://localhost:8080/callback".to_string()) .expect("Invalid redirect URL"));


Generating the authorization URL



Create a link to redirect the user to:



let (auth_url, csrf_token) = client    .authorize_url(CsrfToken::new_random)    .add_scope(Scope::new("openid".to_string()))    .add_scope(Scope::new("email".to_string()))    .url();

println!("Follow the link: {}", auth_url);// Save csrf_token for verification during callback


CsrfToken protects against Cross-Site Request Forgery (CSRF) attacks. It should be temporarily stored (e.g., in a session or cookies) and verified when processing the callback.



Handling the callback and obtaining the token



After the user grants access, the service will redirect them to the redirect_uri with a code parameter. Example handler in Rust:



use actix_web::{web, HttpRequest, HttpResponse};use oauth2::AuthorizationCode;

async fn callback(query: web::Query<std::collections::HashMap<String, String>>) -> HttpResponse { let code = query.get("code") .expect("Missing authorization code"); let state = query.get("state") .expect("Missing state");

// Verify state against the saved csrf_token // ...

let token_result = client .exchange_code(AuthorizationCode::new(code.clone())) .request_async(&reqwest::Client::new()) .await;

match token_result { Ok(token) => { let access_token = token.access_token().secret(); let refresh_token = token.refresh_token() .map(|rt| rt.secret().clone()); // Save tokens in DB or session HttpResponse::Ok().body("Authorization successful!") }, Err(e) => { eprintln!("Code exchange error: {:?}", e); HttpResponse::InternalServer

Recommendations