I have this axum extractor for extracting an authenticated user from a bearer token:
impl FromRequestParts<AppState> for AuthenticatedUser {
type Rejection = Error;
async fn from_request_parts(
parts: &mut Parts,
state: &AppState,
) -> Result<Self, Self::Rejection> {
let TypedHeader(Authorization(bearer)) = parts
.extract::<TypedHeader<Authorization<Bearer>>>()
.await
.map_err(|_| AuthError::MissingToken)?;
let token = bearer.token();
let bearer_token = format!("Bearer {}", token);
match Claims::from_bearer_token(&bearer_token, &state.jwks_cache).await {
Ok(claims) => {
// Extract user information from claims
let user_id = claims
.user_id()
.parse()
.map_err(|_| AuthError::InvalidUserId)?;
// ...
Ok(AuthenticatedUser {
user_id,
// ...
})
}
Err(err) => Err(AuthError::VerificationFailed(err.to_string()).into()),
}
}
}
I now want to add tower-governer to implement rate limiting, where the rate limit key is per authenticated user. For this, I need to implement KeyExtractor for a type. Ideally, I want the key extractor to be the users Uuid, however I don't want each request to perform the bearer token extraction and validation twice on every request (once for KeyExtractor rate limiting, again for the handler to extract the AuthenticatedUser). Any suggestions on how I could make this work be done just once, and still have access to the authenticated user from my extractor?
For now, I've just done the key extraction on the bearer token directly, since thats quite cheap.