在 Actix 中间件中使用异步函数

问题描述 投票:0回答:1

我正在使用 Actix 和 Sqlx 制作 Rust API,目前正在开发 JWT 中间件,大部分已经完成,但我想将授权用户检索到我的端点中。这就是下面的代码正在尝试的,但我遇到了终身问题。

fn call(&self, req: ServiceRequest) -> Self::Future {
    if ApiEnv::skip_auth() {
      return Box::pin(self.service.call(req));
    }

    // Box::pin(self.service.call(req))
    Box::pin(async move {
      let u = {
        let db: &Data<Database> = req.app_data().unwrap();
        let pool = db.pool.clone();
        let headers = req.headers().clone();
        let mut extensions = req.extensions_mut();

        match authorize(pool, headers).await {
          Ok(u) => {
            extensions.insert(u);
            Ok(())
          }, Err(e) => Err(e)
        }
      };
      
      match u {
        Ok(_) => { self.service.call(req).await } 
        Err(e) => Err(e)
      }
    })
  }

我收到以下错误:

error: lifetime may not live long enough
   --> src/middleware/jwt.rs:98:5
    |
92  |     fn call(&self, req: ServiceRequest) -> Self::Future {
    |             - let's call the lifetime of this reference `'1`
...
98  | /     Box::pin(async move {
99  | |       let u = {
100 | |         let db: &Data<Database> = req.app_data().unwrap();
101 | |         let pool = db.pool.clone();
...   |
116 | |       }
117 | |     })
    | |______^ returning this value requires that `'1` must outlive `'static`

我知道这是为什么:我在

self.service.call
内部使用
Box::pin
,但我该如何修复它?

如果我将

self.service.call(req)
移动到 Box::Pin 之外,则
req
值会在我调用
let mut extensions = req.extensions_mut();
extensions.insert(u)
之前移动,所以据我所知,我也不能这样做。

这里有一个非常相似的问题,但所有链接要么导致删除的存储库,要么调用self.service.clone()

,尽管服务没有克隆特征

我很困惑,而且我不是 Box::pin 方面的专家,所以希望有人知道是否有解决方案。感谢您的阅读:)

rust lifetime actix-web rust-futures
1个回答
0
投票
几天后,我弄清楚发生了什么,具有 self.service.clone() 的存储库将 Service 包装在 Rc<> 中,因此能够克隆它。我完全错过了。

© www.soinside.com 2019 - 2024. All rights reserved.