Rust Actix-web中间件未认证提前返回响应触发编译错误问题
问题根因
该返回位置要求的类型是 Result<ServiceResponse<B>, actix_web::Error>,其中B是响应体的泛型参数。
你直接返回Result<HttpResponse, _>类型不满足类型要求:actix-web中间件链路流转的响应是和请求上下文绑定的ServiceResponse,单纯的HttpResponse没有携带对应请求的关联信息,无法直接通过into()转换为中间件要求的返回类型。
另外注意:未认证场景语义上应该返回401状态码,原代码里用200 Ok返回未授权结果不符合HTTP规范。
正确实现
你需要提前保留请求副本,在认证失败分支将构造的HttpResponse和请求绑定,生成符合类型要求的ServiceResponse,修正后的代码如下:
// 提前克隆请求,供认证失败分支构造响应使用(认证通过分支会把原始req move走) let req_for_err = req.clone(); if authenticate_pass { let fut = self.service.call(req); Box::pin(async move { let res = fut.await?; Ok(res) }) } else { Box::pin(async move { let resp = HttpResponse::Unauthorized().json("Unauthorized"); // 绑定请求与响应,构造ServiceResponse Ok(ServiceResponse::new(req_for_err.into_parts().0, resp)) }) }
注意使用前需要导入use actix_web::dev::ServiceResponse;。
简化写法
如果你不需要自定义响应格式,也可以直接返回actix-web内置的未授权错误,框架会自动包装为符合类型要求的响应,代码更简洁:
if authenticate_pass { let fut = self.service.call(req); Box::pin(async move { let res = fut.await?; Ok(res) }) } else { Box::pin(async move { Err(actix_web::error::ErrorUnauthorized("Unauthorized")) }) }
内容的提问来源于stack exchange,提问作者Murtuza Kabul
相关产品推荐
相关产品推荐

