Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Middleware not running (Axum) #1309

Open
rbaprado opened this issue Feb 5, 2025 · 1 comment
Open

Middleware not running (Axum) #1309

rbaprado opened this issue Feb 5, 2025 · 1 comment

Comments

@rbaprado
Copy link

rbaprado commented Feb 5, 2025

Maybe I am missing something here, but my middleware does not get called prior the handler.

Here's my router setup:

pub fn auth_router(state: Arc<AppState>) -> OpenApiRouter {
    OpenApiRouter::new()
        .routes(routes!(post_login))
        .routes(routes!(post_password_reset))
        .routes(routes!(post_password_reset_confirmation))
        .routes(routes!(get_renew).layer(middleware::from_fn_with_state(
            state.clone(),
            auth_middleware,
        )))
        .with_state(state)
}

The middleware function:

#[debug_middleware]
async fn auth_middleware(
    Extension(_state): Extension<Arc<AppState>>,
    jar: CookieJar,
    mut request: Request,
    next: Next,
) -> Result<Response, StatusCode> {
    debug!("Auth middleware");

    // First we try to authenticate using the bearer token
    let authorization_header = request.headers().get(header::AUTHORIZATION);
    if authorization_header.is_none() {
        // Fallback to the authetication token cookie
        let auth_cookie = jar.get("auth_token");
        if auth_cookie.is_none() {
            // Nothing to work with
            return Err(StatusCode::UNAUTHORIZED);
        }
    }

    // Determine the authorization token to check
    let argument = match authorization_header {
        Some(header) => {
            let token_str = header
                .to_str()
                .unwrap()
                .trim_start_matches("Bearer ")
                .to_string();
            token_str
        }
        None => jar.get("auth_token").unwrap().value().to_string(),
    };

    // Perform the actual check
    let decode_result = decode::<Claims>(
        argument.as_str(),
        &DecodingKey::from_secret(TOKEN_SECRET.as_bytes()),
        &Validation::default(),
    );
    if decode_result.is_err() {
        // Invalid or expired token
        return Err(StatusCode::FORBIDDEN);
    }

    // Token is valid, attach user data to the request
    let claims = decode_result.unwrap().claims;
    let authenticated_user = AuthenticatedUser {
        user_id: claims.user_id,
        remember_me: claims.remember_me,
    };
    debug!("Authenticated user extension:");
    request.extensions_mut().insert(authenticated_user);
    Ok(next.run(request).await)
}

The handler:

#[axum::debug_handler]
#[utoipa::path(
    get,
    path = "/renew",
    tag = "auth",
    security(
        ("cookie" = []),
        ("bearer" = [])
    ),
    responses(
        (status = OK, description = "Token renewed", body = LoginResponse),
        (status = FORBIDDEN, description = "Invalid credentials")
    )
)]
pub async fn get_renew(
    Extension(authenticated_user): Extension<AuthenticatedUser>,
    jar: CookieJar,
) -> (StatusCode, CookieJar, Json<LoginResponse>) {
    // TODO: authentication middleware

    // TODO: fetch data from the request extensions

    // Generate the authorization token
    let authorization_data =
        generate_authorization_token(authenticated_user.user_id, authenticated_user.remember_me);

    // Get the authorization response cookie
    let cookie = Cookie::build(("auth_token", authorization_data.token.clone()))
        .path("/")
        .expires(authorization_data.expiration_date)
        .secure(true)
        .http_only(true);

    // All good
    (
        StatusCode::OK,
        jar.add(cookie),
        Json(LoginResponse {
            message: "User authenticated".to_string(),
            auth_token: Some(authorization_data.token),
        }),
    )
}

I am basing this approach on @juhaku 's reply to #1296

@rbaprado rbaprado changed the title Middleware not running Middleware not running (Axum) Feb 6, 2025
@rbaprado
Copy link
Author

rbaprado commented Feb 6, 2025

Just closing it myself, dumb error on Extension(_state): Extension<Arc<AppState>>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant