2 releases
Uses new Rust 2024
| 0.0.2 | Nov 2, 2025 |
|---|---|
| 0.0.1 | Apr 9, 2019 |
#311 in HTTP server
36KB
690 lines
OAuth Adapter for Rust Web Frameworks
A universal OAuth 2.0 adapter for Rust web frameworks, providing a single configuration model and framework-specific glue so you can expose compliant token endpoints without duplicating logic.
Status: This crate is still in active development. The API described below represents the intended shape of the crate and may change before the first stable release.
Highlights
- Framework agnostic support for Axum, Warp, Actix-web, and Rocket
- Shared
OAuthConfigbuilder for consistent client credentials and token settings - Pluggable token store interface for Redis, SQL, or in-memory implementations
- Opinionated defaults with escape hatches for custom validation and token generation
Notice
⚠️ This crate is in early development. For production use, consider oauth2 as a mature alternative solution.
Installation
Add the crate to your Cargo.toml, enabling the integration you need:
[dependencies]
oauth = { version = "0.1.0", default-features = false, features = ["axum"] }
Available feature flags: axum, warp, actix, rocket. Combine them if you support multiple frameworks in the same binary.
Configuration At A Glance
Create an OAuthConfig once and share it across the adapters you enable:
use oauth::OAuthConfig;
let config = OAuthConfig::builder()
.client_id("your-client-id")
.client_secret("your-client-secret")
.issuer("https://auth.example.com")
.access_token_ttl(std::time::Duration::from_secs(3600))
.refresh_token_ttl(std::time::Duration::from_secs(7 * 24 * 3600))
.enable_refresh_tokens(true)
.build()
.expect("valid OAuth configuration");
The builder validates required fields and returns a Result<OAuthConfig, ConfigError>. Keep the resulting value in an Arc if you need to clone it between routes or filters.
Custom Token Storage
To persist tokens outside the default in-memory store, implement TokenStore and attach it to the configuration:
use oauth::{OAuthConfig, TokenStore, TokenRecord};
struct CustomTokenStore;
impl TokenStore for CustomTokenStore {
fn save(&self, token: TokenRecord) -> oauth::Result<()> {
// Write to Redis, PostgreSQL, or another backend
todo!("store token: {token:?}");
}
fn revoke(&self, token_id: &str) -> oauth::Result<()> {
// Remove the token from your backend
todo!("revoke token: {token_id}");
}
}
let config = OAuthConfig::builder()
.client_id("your-client-id")
.client_secret("your-client-secret")
.token_store(CustomTokenStore)
.build()
.expect("valid OAuth configuration with custom store");
Framework Quick Starts
Each framework-specific integration exposes a thin wrapper that turns an OAuthConfig into the appropriate route handler.
Axum
use std::sync::Arc;
use axum::{routing::post, Router};
use oauth::axum::OAuthHandler;
use oauth::OAuthConfig;
#[tokio::main]
async fn main() {
let config = Arc::new(
OAuthConfig::builder()
.client_id("your-client-id")
.client_secret("your-client-secret")
.build()
.expect("valid OAuth configuration"),
);
let oauth = OAuthHandler::from_config(config.clone());
let app = Router::new().route("/oauth/token", post(oauth.token_endpoint()));
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
Warp
use std::sync::Arc;
use oauth::warp::oauth_filter;
use oauth::OAuthConfig;
use warp::Filter;
#[tokio::main]
async fn main() {
let config = Arc::new(
OAuthConfig::builder()
.client_id("your-client-id")
.client_secret("your-client-secret")
.build()
.expect("valid OAuth configuration"),
);
let oauth_route = warp::path!("oauth" / "token")
.and(oauth_filter(config.clone()));
warp::serve(oauth_route)
.run(([0, 0, 0, 0], 3000))
.await;
}
Actix-web
use std::sync::Arc;
use actix_web::{App, HttpServer};
use oauth::actix::configure_oauth;
use oauth::OAuthConfig;
#[actix_web::main]
async fn main() -> std::io::Result<()> {
let config = Arc::new(
OAuthConfig::builder()
.client_id("your-client-id")
.client_secret("your-client-secret")
.build()
.expect("valid OAuth configuration"),
);
HttpServer::new(move || {
App::new().configure(|cfg| configure_oauth(cfg, config.clone()))
})
.bind(("0.0.0.0", 3000))?
.run()
.await
}
Rocket
use std::sync::Arc;
use oauth::rocket::oauth_routes;
use oauth::OAuthConfig;
use rocket::launch;
#[launch]
fn rocket() -> _ {
let config = Arc::new(
OAuthConfig::builder()
.client_id("your-client-id")
.client_secret("your-client-secret")
.build()
.expect("valid OAuth configuration"),
);
rocket::build().mount("/", oauth_routes(config))
}
Supported OAuth 2.0 Grants
The adapter aims to cover the following grant types out of the box:
- Client Credentials
- Authorization Code (with PKCE support)
- Refresh Token
Additional flows (Device Code, Resource Owner Password) are planned once the core API stabilizes.
Token Endpoint Contract
All integrations expose a standardized token endpoint that accepts JSON requests:
{
"grant_type": "client_credentials",
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"scope": "read:payments write:payments"
}
Successful responses return RFC 6749-compliant JSON:
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "optional-refresh-token"
}
Contributing
We welcome pull requests and issues that help shape the API.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit (
git commit -m "feat: add amazing feature") - Push (
git push origin feature/amazing-feature) - Open a Pull Request
License
Distributed under the MIT License. See the LICENSE file for details.
Acknowledgements
- Inspired by the need for a unified OAuth solution across Rust web frameworks
- Built with ❤️ for the Rust community
Dependencies
~26–64MB
~1M SLoC