Tower middleware to parse JWT tokens off the Authorization Bearer of requests and store the deserialized claims on the
request extension.
Since this is a Tower middleware it can be used on any framework like Axum, Tonic, etc.
Example
use http::{Request, Response, StatusCode};
use hyper::Body;
use serde::Deserialize;
use std::{convert::Infallible, iter::once};
use tower::{Service, ServiceBuilder, ServiceExt};
use tower_jwt::{JwtLayer, RequestClaim};
#[derive(Clone, Deserialize, Debug)]
struct Claim {
pub sub: String,
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
async fn handle(req: Request<Body>) -> Result<Response<Body>, Infallible> {
let claim = req.extensions().get::<RequestClaim<Claim>>();
if let Some(claim) = claim {
Ok(Response::new(Body::empty()))
} else {
Ok(Response::builder()
.status(StatusCode::UNAUTHORIZED)
.body(Body::empty())
.unwrap())
}
}
let jwt_layer = JwtLayer::<Claim, _>::new("issuer", || {
async { Vec::new() }
});
let mut service = ServiceBuilder::new().layer(jwt_layer).service_fn(handle);
let request = Request::builder().uri("/").body(Body::empty())?;
let status = service.ready().await?.call(request).await?.status();
assert_eq!(
status,
StatusCode::UNAUTHORIZED,
"request did not have a token while endpoint expected one"
);
Ok(())
}