Search code examples
phplaravelrequestjwtmiddleware

Pass user object to controller through request from jwt middleware?


I have a simple case and I need your advice. I am using tymon jwt package. I have JWT middleware and this is the part of it's code:

     $user = JWTAuth::parseToken()->authenticate();
     if(!$user){
         return response()->json(['message'=>trans("responseMessages.user_not_exists")], 403);
     }
     $request->request->set('user', $user);

what this middleware does, is that it tries to create $user from given jwt token, if it succeeds, user is good to continue. so here is my question, in this code (final line) I pass user object to controller through request, so I can directly have access to user model in controller. I am just interested, is this a good idea? or maybe this will be problematic?

other option is to write $user = JWTAuth::toUser(JWTAuth::getToken()) in controller function or pass user id through request instead of whole model. but in these cases I communicate with database twice, in middleware and in controller in order to get user object.

also I tried to do something like that in controller constructor : $this->user = JWTAuth::toUser(JWTAuth::getToken()), but controller constructor executes before middleware so this one was problematic. so provide me with your ideas and advices if passing user model is good idea or not.


Solution

  • This is an opinionated question, so don't take my answer as your final solution.

    I use Slim and made an authenticate-middleware that adds the user object to the request attributes. This is essentially what you are doing.

    Keep in mind the folllowing problems though (at least with immutables Request/Response objects like with PSR7):

    1. when you have middlewares BEFORE your authentication middleware (like catching Exceptions), the request does NOT have the user object, because the middlewares work in layers.
    2. Vice versa: if you have middleware that first executes all other middleware and than executes itself

    It's just pseudo-code, but you get the idea.

    middlewarefunction($request, $response, $nextmiddleware) 
    {
      $nextmiddleware->do($request, $response);
      // from here on the $request has nothing set to the request by the $nextMiddleware
      // because it is immutable
    }
    

    // Edit If you look at other middlewares, they are setting the request attribute with the decoded JWT token too: https://github.com/DASPRiD/Helios/blob/master/src/IdentityMiddleware.php https://github.com/tuupola/slim-jwt-auth/blob/3.x/src/JwtAuthentication.php