I'm trying to write an authentication middleware for my Actix application. When validating the request in the middleware, I make a call to a database to retrieve the necessary user data to validate the incoming request. Once the request has been authorised, I want to be able to pass this user data to the handler as this will allow me to avoid having the query for the same data twice.
I can't find a solution for this. The best suggestion I could find so far was to "set a request extension". There doesn't seem to be any examples for this and there is also too little documentation around this to work out what to do here.
You can pass data from middleware (service) to handler via extensions.
First of all you have to insert extension (in service).
The HttpMessage
trait is implemented for ServiceRequest
struct and provides extensions_mut()
function. It must be mutable because you will be inserting new extension.
It might look something like this:
req.extensions_mut().insert(user);
Then you have to implement FromRequest
trait for your data structure.
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..."))
};
}
}
Then you're ready to use it in handler.
pub async fn get_user_handler(user: User) {}