I will need json body in router handler too so if it consumes I think I may need to inject it again. If there is other way I would use it. I need to check function body because I have to check if user modifies it's own property or others. I mean I'm trying to implement is_self mechanism if you familiar with other frameworks like Django.
By the way putting Json at the end didn't solve the problem. I don't know why but even this (without json only appstate) is not working:
That's weird, I just tested your middleware locally and it works as expected. Try annotating your middleware function with the #[debug_middleware] macro and also post the full compilation error.
A quick search for is_self django didn't return any meaningful results. Perhaps you could also post a link to what exactly you're after.
I tried Result<impl IntoResponse, StatusCode> instead of impl IntroResponse too.
sorry for being so specific when I said is_self in Django, i meant: Is request object belongs to the same person who sends request. It does it with object permission mechanism and basically checks if user_id in jwt token same with user_id in request object body. It tries to match user.
I was thinking of a custom extractor UserJson that implements FromRequest and that you use instead of the Json extractor as argument to your handlers that require the validation of the user data in the body against the JWT.
This seems an uncommon check to me. I usually have my user endpoints behind a /user/{id}, that way I can check my JWT against the id in my path, without having to look at the body of my request.
You are not showing the implementation for user_extraction, but given the error you are getting I'm betting you are consuming the request body. That's why I warned you against following this path.
I never done this, can you give me a little example about it?
I have different kind of endpoints. Sometimes it's like your example especially in get requests but for post, update request I need to check with body.
The output of #[debug_middleware] contained more information that was useful to understand the issue. In the future please post the full output so that we can better help you.
The issue is that you are passing a reference to an async function (You pass a reference to Request in user_extraction), but this can only work if their referent is Sync (which is not the case for Request).
Unfortunately this means that you'll have to extract the user within the middleware function.
Thanks a lot, I fixed problem with sending request and returning it back instead of only sharing reference.
Now we can pass to another part. I need to parse body as a Json but I cant use both
Request and Json extractor together. (Thanks a lot btw, #[debug_middleware] gives perfect feedback)
Can't have two extractors that consume the request body. `Json<_>` and `Request<_>` both do that.
So I think I have to do it manually by checking request body but how can I deserialize it as json and check specific field?
In OpenID Connect you can add custom claims to your JWT. That could be admin: true, for example. If you are using some other protocol, I'm sure there is a similar way for you to add application-specific metadata to your JWT. That way you'd know that a user is an admin and that they can change the user data for other users. Then we are back at
I don't know if it's going to work but I'm extracting json and "kind of" cloning body.
let (parts, body) = request.into_parts();
let bytes = to_bytes(body, usize::MAX).await?;
let json: serde_json::Value = serde_json::from_slice(&bytes)?;
let body = Body::from(json.to_string());
let request = Request::from_parts(parts, body);