rust 46 lines · 7 steps

How bearer-auth middleware works in Axum

An Axum middleware that extracts and verifies a Bearer token, then hands the authenticated user to downstream handlers.

Explained by highlit
1use axum::{
2 body::Body,
3 extract::Request,
4 http::{header, StatusCode},
5 middleware::Next,
6 response::{IntoResponse, Response},
7 Json,
8};
9use serde_json::json;
10 
11#[derive(Clone)]
12pub struct AuthUser {
13 pub id: i64,
14 pub scopes: Vec<String>,
15}
16 
17pub async fn require_bearer(mut req: Request<Body>, next: Next) -> Response {
18 let token = req
19 .headers()
20 .get(header::AUTHORIZATION)
21 .and_then(|value| value.to_str().ok())
22 .and_then(|value| value.strip_prefix("Bearer "))
23 .map(str::trim);
24 
25 let token = match token {
26 Some(token) if !token.is_empty() => token,
27 _ => return unauthorized("missing or malformed Authorization header"),
28 };
29 
30 match verify_token(token).await {
31 Ok(user) => {
32 req.extensions_mut().insert(user);
33 next.run(req).await
34 }
35 Err(_) => unauthorized("invalid or expired token"),
36 }
37}
38 
39fn unauthorized(detail: &str) -> Response {
40 (
41 StatusCode::UNAUTHORIZED,
42 [(header::WWW_AUTHENTICATE, "Bearer")],
43 Json(json!({ "error": "unauthorized", "detail": detail })),
44 )
45 .into_response()
46}
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Middleware can validate requests and short-circuit with a response before the handler ever runs.
  2. 2Request extensions are the idiomatic way to pass derived data like an authenticated user down the Axum stack.
  3. 3Chaining Option combinators lets you parse a header safely without nested matches or panics.

Related explainers

Share this explainer

Here's the card — post it anywhere.

How bearer-auth middleware works in Axum — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code