I've been doing rust for just short while but didn't much struggle until this issue. I want to authenticate each request, and make returned value (from auth service) available inside requests.
I've read implementing FromRequest for the struct returned by auth server should make it available.
But I have issues implementing it correctly. It requires extract
and from_request
functions both returning self, and if I understand it a little correctly, extract is being called the first, so I should set it somewhere in request extensions, and get it from there inside from_request. I have following code:
impl FromRequest for CustomClaim {
type Error = actix_web::Error;
type Future = std::pin::Pin<Box<dyn std::future::Future<Output = Result<Self, Self::Error>>>>;
fn extract(req: &HttpRequest) -> Self::Future {
let auth_header = req
.headers()
.get("Authorization")
.unwrap()
.to_str()
.unwrap()
.to_owned();
let boxed_future = Box::pin(async move {
let claim_future = get_claim(&auth_header).await;
claim_future
});
req.extensions_mut().insert(boxed_future);
boxed_future
}
fn from_request(req: &HttpRequest, payload: &mut actix_web::dev::Payload) -> Self::Future {
let boxed_future = req.extensions().get::<Self::Future>().unwrap();
boxed_future
}
}
async fn get_claim(auth_header: &str) -> Result<CustomClaim, actix_web::Error>
But from_request doesn't compile because it returns a reference (error message: mismatched types expected struct `Pin\<Box\<(dyn futures::Future\<Output = Result\<auth::CustomClaim, actix_web::Error\>\> + 'static)\>\>`found reference`&Pin\<Box\<dyn futures::Future\<Output = Result\<auth::CustomClaim, actix_web::Error\>\>\>\>`
)
Doing .clone() doesn't help because clone is not implemented on that future type so it still returns a reference. Can I implement clone for the future? Is my approach wrong?