OAuth client for Rust: oauth2 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

OAuth client for Rust: oauth2 library

OAuth 2.0 is the industry standard for delegated access. It is widely used for authorizing users through third-party services (Google, GitHub, Facebook) without sharing a password. In the Rust ecosystem, one of the most popular and mature libraries for implementing OAuth 2.0 is oauth2 (crate oauth2). It provides a secure, asynchronous, and flexible API for working with any OAuth providers.



Key Features

  • Support for all standard grants: Authorization Code, Client Credentials, Resource Owner Password Credentials, Implicit.
  • Built-in PKCE support (Proof Key for Code Exchange) for enhanced security of public clients.
  • Asynchronous operation using reqwest or ureq under the hood.
  • Type safety: all tokens, URLs, and parameters are strictly typed, preventing errors at compile time.
  • Flexible configuration for any provider via endpoint and scope configuration.
  • Token management: automatic refresh, expiration checking.


Installation

Add the dependency to your Cargo.toml:

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


Basic example: authorization via Google

Let's look at the full OAuth 2.0 flow with the Authorization Code + PKCE grant for 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. Create a client with Google settings let client = BasicClient::new( ClientId::new("YOUR_GOOGLE_CLIENT_ID".to_string()), Some(ClientSecret::new("YOUR_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. Generate PKCE challenge let (pkce_challenge, pkce_verifier) = PkceCodeChallenge::new_random_sha256();

// 3. Build the URL for user authorization 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!("Open in browser: {}", auth_url);

// 4. (Simulation) get the authorization code from the user let code = "code_from_browser_after_redirect";

// 5. Exchange the code for a token 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(())}


Advanced scenarios

1. Token refresh (Refresh Token)

When the access token expires, use the refresh token to obtain a new one:

use oauth2::RefreshToken;

let refresh_token = RefreshToken::new("your_refresh_token".to_string());let new_token = client .exchange_refresh_token(&refresh_token) .requ

Recommendations