如何将结构从 Actix 中间件传递到处理程序?

Rob*_*123 7 rust actix-web

我正在尝试为我的 Actix 应用程序编写一个身份验证中间件。在中间件中验证请求时,我调用数据库来检索必要的用户数据以验证传入的请求。一旦请求获得授权,我希望能够将此用户数据传递给处理程序,因为这将使我避免两次查询相同的数据。

我无法找到解决方案。到目前为止我能找到的最好的建议是“设置请求扩展”。似乎没有任何这方面的示例,而且围绕此的文档也太少,无法弄清楚这里要做什么。

小智 12

您可以通过扩展将数据从中间件(服务)传递到处理程序。

首先,您必须插入扩展(在服务中)。该HttpMessage特征是为ServiceRequest结构实现的并提供extensions_mut()函数。它必须是可变的,因为您将插入新的扩展。

它可能看起来像这样:

req.extensions_mut().insert(user);
Run Code Online (Sandbox Code Playgroud)

然后你必须FromRequest为你的数据结构实现特征。

impl FromRequest for User {
    type Error = actix_web::Error;
    type Future = futures::future::Ready<Result<Self, Self::Error>>;
    type Config = ();

    fn from_request(req: &HttpRequest, payload: &mut Payload) -> Self::Future {
        match req.extensions().get::<User>() {
            Some(user) => return ok(user.clone()),
            None => return err(actix_web::error::ErrorBadRequest("ups..."))
        };
    }

}
Run Code Online (Sandbox Code Playgroud)

然后您就可以在处理程序中使用它了。

pub async fn get_user_handler(user: User) {}
Run Code Online (Sandbox Code Playgroud)

  • 从 actix-web 3.2.0 开始,有 [`ReqData`](https://docs.rs/actix-web/3.3.2/actix_web/web/struct.ReqData.html) 提取器。因此,您可以在处理程序中使用“ReqData&lt;User&gt;”参数,而不是为“User”实现“FromRequest”。 (3认同)