Axum 0.7.5认证中间件编译失败问题求助
Axum 0.7.5 中间件编译失败问题解决
问题背景
使用Axum 0.7.5构建后端服务时,自定义的auth_middleware无法通过编译,初始报错提示tower_service::Service trait未实现,添加#[axum::debug_middleware]后暴露了更深层的Send安全问题。
初始编译错误
error[E0277]: the trait bound `axum::middleware::FromFn<fn(hyper::Request<axum::body::Body>, Next) -> impl Future<Output = Result<Response<axum::body::Body>, StatusCode>> {auth_middleware}, (), Route, _>: tower_service::Service<hyper::Request<axum::body::Body>>` is not satisfied --> src/routes/mod.rs:40:16 | 40 | .layer(from_fn(auth_middleware)) | ----- ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `tower_service::Service<hyper::Request<axum::body::Body>>` is not implemented for `axum::middleware::FromFn<fn(hyper::Request<axum::body::Body>, Next) -> impl Future<Output = Result<Response<axum::body::Body>, StatusCode>> {auth_middleware}, (), Route, _>` | | | required by a bound introduced by this call | = help: the following other types implement trait `tower_service::Service<Request>`: axum::middleware::FromFn<F, S, I, (T1, T2)> axum::middleware::FromFn<F, S, I, (T1, T2, T3)> axum::middleware::FromFn<F, S, I, (T1, T2, T3, T4)> axum::middleware::FromFn<F, S, I, (T1, T2, T3, T4, T5)> axum::middleware::FromFn<F, S, I, (T1, T2, T3, T4, T5, T6)> axum::middleware::FromFn<F, S, I, (T1, T2, T3, T4, T5, T6, T7)> axum::middleware::FromFn<F, S, I, (T1, T2, T3, T4, T5, T6, T7, T8)> axum::middleware::FromFn<F, S, I, (T1, T2, T3, T4, T5, T6, T7, T8, T9)> and 8 others note: required by a bound in `Router::<S>::layer` --> /home/admin/.cargo/registry/src/index.crates.io-6f17d22bba15001f/axum-0.7.7/src/routing/mod.rs:279:21 | 276 | pub fn layer<L>(self, layer: L) -> Router<S> | ----- required by a bound in this associated function ... 279 | L::Service: Service<Request> + Clone + Send + 'static, | ^^^^^^^^^^^^^^^^ required by this bound in `Router::<S>::layer`
排查过程
为定位问题,给auth_middleware添加#[axum::debug_middleware]属性后,得到更明确的错误提示:
error: future cannot be sent between threads safely --> src/middleware/auth_middleware.rs:9:1 | 9 | #[axum::debug_middleware] | ^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `auth_middleware` is not `Send` | = help: the trait `Send` is not implemented for `dyn StdError`, which is required by `impl Future<Output = Result<Response<axum::body::Body>, StatusCode>>: Send` note: future is not `Send` as this value is used across an await --> src/middleware/auth_middleware.rs:50:30 | 41 | match decode_token( | ___________- 42 | | token, 43 | | true, // Indicates that we're validating an access token 44 | | &state.access_token_secret, 45 | | &state.refresh_token_secret, 46 | | ) { | |_____- has type `Result<TokenContent, Box<dyn StdError>>` which is not `Send` ... 50 | Ok(next.run(req).await) | ^^^^^ await occurs here, with the value maybe used later note: required by a bound in `__axum_macros_check_auth_middleware_future::check` --> src/middleware/auth_middleware.rs:9:1 | 9 | #[axum::debug_middleware] | ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `check`
解决方案
将decode_token函数的返回类型从Result<TokenContent, Box<dyn std::error::Error>>修改为:
Result<TokenContent, Box<dyn std::error::Error + Send + Sync>>
原因分析
Axum 0.7+版本的中间件要求其返回的Future必须实现Send trait,因为Axum服务运行在多线程环境中,需要在线程间安全传递Future。
原decode_token返回的Box<dyn Error>默认不包含Send和Sync约束,导致auth_middleware返回的Future因持有非Send类型的错误对象而无法实现Send,进而导致FromFn类型无法满足Service trait的约束,触发初始编译错误。添加Send + Sync约束后,错误对象可安全在线程间传递,Future满足Send要求,最终解决编译问题。
内容的提问来源于stack exchange,提问作者oas
相关产品推荐
相关产品推荐

