#Custom middleware(s) at resource level using macros.

1 messages · Page 1 of 1 (latest)

light quarry
#

I would like this request to pass through a custom middleware, and possibly another one called VerifyPoPMiddleware. However, I receive this error:"

  • expected value, found struct VerifyTokenPresentationMiddleware, help: use struct literal syntax instead: VerifyTokenPresentationMiddleware { service: val }
#[get("/assets/{asset_id}/download", wrap="VerifyTokenPresentationMiddleware" )] 
async fn download_asset(
    req: HttpRequest,
    path: web::Path<i64>,
    db_pool: web::Data<Pool>,
) -> ... ```

The middleware that I am currently using is the  `SayHiMiddleware` that you provided in the documentation. However, for the specific middleware I need, I have to extract a JWT from the request header and perform a custom verification.
light quarry
#

The API is registered like this:

// this function could be located in a different module
pub fn scoped_config(cfg: &mut web::ServiceConfig) {
    cfg  
    .service(upload_asset)
    .service(download_asset)       
    .service(patch_asset)
}
zenith gulch
light quarry
#

Thanks! It was so simple...

#

@zenith gulch What about multiple middlewares? In js, I would do something like this:

router.get("/hello-world", verifyTokenPresentationMiddleware, verifyPoPMiddleware, (req, res) => {
    res.json('Hello World!')
}); 
zenith gulch
#

I’ve never done it but I’m pretty sure you can use wrap twice there. Though at that point it may be cleaner to use a new configure method and a manually written out resource definition.

light quarry
light quarry
#

Yes, I confirm, wrap can be used twice

light quarry
#

Hi @zenith gulch, In the end, since I had to use async, I opted for from_fn. I am very happy with the code simplicity. Thanks for your work. My only question is, how can I pass outputs (structs) from one middleware to another or to the handler, given that the only action I perform is next.call(req)?

pub async fn my_foo_mw(
    req: ServiceRequest,
    next: Next<impl MessageBody>,
) -> Result<ServiceResponse<impl MessageBody>, Error> {
    // pre-processing
    log::info!("Hi from start 3");
    next.call(req).await
    // post-processing
}
light quarry
#

I'll try! Thanks

light quarry
#

Hi @zenith gulch, thank you for your help in the past few days. I ended up writing two middlewares, and request extensions work when used in the handler.
I'm trying to add the extension in one middleware and pass it to the other one. But in the macro of the handler on wrap = "from_fn(verify_proof_of_purchase)" , I get the following error and my first idea is that I need to specify in from_fn<...> that the second middleware accepts an extension.

the trait bound `MiddlewareFn<fn(ServiceRequest, actix_web_lab::middleware::Next<_>, std::option::Option<ReqData<ProofOfPurchaseRequest>>) -> impl futures_util::Future<Output = Result<ServiceResponse<impl MessageBody>, actix_web::Error>> {verify_proof_of_purchase::<_>}, _>: Transform<actix_web::resource::ResourceService, ServiceRequest>` is not satisfied the following other types implement trait `Transform<S, Req>`: MiddlewareFn<F, ()> MiddlewareFn<F, (E1,)> MiddlewareFn<F, (E1, E2)> MiddlewareFn<F, (E1, E2, E3)> MiddlewareFn<F, (E1, E2, E3, E4)> MiddlewareFn<F, (E1, E2, E3, E4, E5)> MiddlewareFn<F, (E1, E2, E3, E4, E5, E6)> MiddlewareFn<F, (E1, E2, E3, E4, E5, E6, E7)> and 2 others

Here the code two middlewares and the handler

pub async fn verify_presentation_jwt(
    req: ServiceRequest,
    next: Next<impl MessageBody>,
) -> Result<ServiceResponse<impl MessageBody>, Error> { 
  // ...  
  req.extensions_mut().insert( ProofOfPurchaseRequest { ... });
  // ... 
}
pub async fn verify_proof_of_purchase(
    req: ServiceRequest,
    next: Next<impl MessageBody>,
    msg: Option<ReqData<ProofOfPurchaseRequest>>,
) -> Result<ServiceResponse<impl MessageBody>, Error> { ... }
#[get("/assets/download", 
wrap = "from_fn(verify_proof_of_purchase)", 
wrap = "from_fn(verify_presentation_jwt)")]
async fn download_asset(
    req: HttpRequest,
    query_params: web::Query<QueryAssetAlias>, 
    db_pool: web::Data<Pool>,
) -> ... { ... } ```
zenith gulch
#

The msg parameter/extractor needs to go before req I think