Skip to main content
If your backend is built in Rust using the axum web framework, you can use Wacht’s pre-built AuthLayer to automatically validate incoming JSON Web Tokens (JWTs) attached to request headers. This middleware ensures that every request hitting your protected routes is authenticated, untampered, and unexpired.

Setting up the AuthLayer

To start validating tokens, add the AuthLayer to your Axum router. Ensure you have the axum feature enabled in your Cargo.toml.
use axum::{routing::get, Router};
use wacht::middleware::{AuthLayer, RequireAuth};

async fn protected_endpoint(auth: RequireAuth) -> &'static str {
    // If we reach this handler, the token was valid!
    "You are authenticated."
}

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // 1. Initialize the Wacht SDK from the environment
    wacht::init_from_env().await?;

    // 2. Attach the AuthLayer to the router
    let app = Router::new()
        .route("/protected", get(protected_endpoint))
        .layer(AuthLayer::new());

    // 3. Serve the application
    let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
    axum::serve(listener, app).await?;
    
    Ok(())
}

How the Validation Works

When a request passes through the AuthLayer, the SDK performs the following checks in order:
  1. Token Extraction: The middleware looks for a Bearer token in the Authorization HTTP header (Authorization: Bearer <token>).
  2. Signature Verification: The token’s signature is cryptographically verified against your deployment’s JSON Web Key Set (JWKS). By default, the SDK dynamically fetches and caches these public keys directly from your Frontend API.
  3. Expiration Check: The token’s exp (Expiration Time) claim is verified to ensure the session is still active. The nbf (Not Before) claim is also checked.
If any of these checks fail, the middleware immediately rejects the request with a 401 Unauthorized status code, and your route handler is never executed.

Configuration Options

While AuthLayer::new() uses secure defaults, you can customize the validation behavior if necessary.

Clock Skew Tolerance

Due to minor differences in server clocks, it’s common to allow a small buffer window when checking expiration tags. The SDK defaults to a 5-second tolerance.
use wacht::middleware::AuthLayer;

// Increase clock skew tolerance to 15 seconds
let auth_layer = AuthLayer::new().allowed_clock_skew(15);

Bypassing Expiration (Development Only)

If you are writing local tests and need to use mock tokens that have expired, you can disable the expiration check. Never do this in production.
let test_layer = AuthLayer::new().validate_exp(false);