I'm making a rust API with Actix and Sqlx, and currently working on a JWT middleware, it's mostly done, but I'd like to retrieve the authorized user into my endpoints. That's what the code below is attempting, but I'm running into a lifetime issue.
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)
}
})
}
I'm getting the following error:
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`
I know why this is: I'm using self.service.call
inside of a Box::pin
, but how do i fix it?
If I move self.service.call(req)
outside of the Box::Pin, the req
value is moved before i call let mut extensions = req.extensions_mut();
and extensions.insert(u)
, so as far as i know, i can't do that either.
There was a very similar issue here, but all the links either lead to deleted repo's, or one that calls self.service.clone()
, despite Service not having a Clone trait
I'm pretty stuck, and I'm not an expert on Box::pin, so hopefully someone knows if there's a solution to this. Thanks for reading :)
After a few days I figured what was going on, the repo that had self.service.clone() wrapped Service in a Rc<> therefore being able to clone it. I missed it completely.