-
New to Rust and don't understand lifetimes very well yet. I'm trying to implement user auth, with active and return cookies. I have a TokenService in the request context that can validate the cookies. This service is added to the request context. It's async. I can extract the cookies from the request by implementing the FromRequest trait. But as soon as I try to call the TokenService, I get lifetime issues. I tried using Box::pin as per this SO: https://stackoverflow.com/questions/63308246/how-to-use-async-code-in-actix-web-extractors. But I get an error that request doesn't satisfy the lifetime requirements. Trying to add 'static anywhere throws even more errors. Questions:
The error:
The code: use crate::modules::auth::services::TokenService;
use actix_web::{cookie, dev, Error, FromRequest, HttpRequest};
use async_std::task;
use chrono::{DateTime, Utc};
use futures_util::future::{err, ok, Future, Ready};
use std::pin::Pin;
pub struct Token {
pub user_id: i32,
pub value: String,
pub expires: DateTime<Utc>,
}
impl FromRequest for Token {
type Error = Error;
type Future = Pin<Box<dyn Future<Output = Result<Self, Self::Error>>>>;
type Config = ();
fn from_request(req: &HttpRequest, _: &mut dev::Payload) -> Self::Future {
// req doesn't satisfy lifetime requirement
let service = req.app_data::<TokenService>().unwrap().clone();
Box::pin(async move {
let from_headers = match req.headers().get("cookie") {
Some(cookie) => cookie,
None => {
return Err(actix_web::error::ErrorForbidden(format!(
"Authentication Cookie Not Found"
)))
}
};
let as_str = match from_headers.to_str() {
Ok(cookie) => cookie,
Err(_) => {
return Err(actix_web::error::ErrorForbidden(format!(
"Invalid Cookie"
)))
}
};
let parsed = match cookie::Cookie::parse(as_str) {
Ok(cookie) => cookie,
Err(_) => {
return Err(actix_web::error::ErrorForbidden(format!(
"Invalid Cookie"
)))
}
};
let token_result = service.validate(format!("test")).await;
return match token_result {
Ok(token) => Ok(Token {
expires: token.expires,
user_id: token.user_id,
value: token.value,
}),
Err(_) => {
Err(actix_web::error::ErrorForbidden(format!("Invalid Cookie")))
}
};
})
}
} |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 7 replies
-
HttpRequest is cheap to clone and will give you the 'static lifetime needed to use it (or it's parts) in the async block. Your approach looks fine. |
Beta Was this translation helpful? Give feedback.
HttpRequest is cheap to clone and will give you the 'static lifetime needed to use it (or it's parts) in the async block.
Your approach looks fine.