7356

How to bind user object to request in a middleware

i'm writing an application in Laravel Spark 1.0 (Laravel 5.2). I wrote a custom middleware for agent (api) authentication. This is the code:

<?php namespace App\Http\Middleware; use App\Agent; use Closure; use Illuminate\Http\Request; class AgentAuth { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @return mixed */ public function handle($request, Closure $next) { if( isset($request->token) && !empty($request->token) ) { $agent = Agent::where('token', '=', $request->token)->first(); if( $agent != NULL ) { $team = $agent->Team()->first(); $user = $team->User()->first(); $request->merge(['team' => $team ]); $request->merge(['user' => $user ]); return $next($request); } else { return response('Unauthorized 2.', 401); } } else { return response('Unauthorized 1.', 401); } } }

In the default laravel authentication the user object is injected in the request (see laravel docs): https://laravel.com/docs/5.2/authentication#retrieving-the-authenticated-user

So you can retrieve the user using:

$request->user();

Spark obviously use this method to check if user subscription is valid (laravel\spark\src\Http\Middleware\VerifyUserIsSubscribed):

if ($this->subscribed($request->user(), $subscription, $plan, func_num_args() === 2)) { return $next($request); }

And it's not working because, with my middleware, you can retrieve the user using: $request->user; but not with the laravel defaults $request->user();

How should i inject the user object into the request?

Thank you in advance

<strong>EDIT:</strong>

Laravel in the service provider (Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler)

Use this code to bind object user to the request:

/** * Register a resolver for the authenticated user. * * @return void */ protected function registerRequestRebindHandler() { $this->app->rebinding('request', function ($app, $request) { $request->setUserResolver(function ($guard = null) use ($app) { return call_user_func($app['auth']->userResolver(), $guard); }); }); }

I tried to insert this code, with the appropriate correction, in the middleware but i can't figure out how to make it work.

Answer1:

I don't have a copy of Spark to try this & ensure what I'm doing is correct for you, but I think this will help:

1) An assumption - I believe you are saying that yes, this line will get you the user you want:

$user = $team->User()->first();

and you merely want to bind it to the request so that you can access this user later in your app via:

$request->user()

2) If this is true, then all I did was simplify the code you provided to add:

$request->merge(['user' => $user ]); //add this $request->setUserResolver(function () use ($user) { return $user; }); // if you dump() you can now see the $request has it dump($request->user()); return $next($request);

I also $request->user() in the route closure, and it is there.

The app rebinding was a little strange to me, and didn't seem necessary. I'm not sure that anything would really need this for what you are doing.

Answer2:

You could use the auth system if that model implements the right interface, to log them in for the request.

Auth uses a rebinder to assign the userResolver on request. (So you get $request->user() from it). Check Illuminate\Auth\AuthServiceProvider@registerRequestRebindHandler to see how its setting that resolver.

$request->setUserResolver(....)

Answer3:

This is a very useful question. I was having trouble with the selected solution though. In my middleware I could successfully see $request->user(), however it was failing when using gates, namely in the Access/Gate class:

protected function raw($ability, $arguments = []) { if (! $user = $this->resolveUser()) { return false; } // ...

This function is always returning false :/

So I did it as suggested here (http://laravel-recipes.com/recipes/230/setting-the-currently-authenticated-user), namely:

$usr = new User(); $usr->setAttribute('id', $request->user_id); Auth::setUser($usr);

And it appears to be working without using setUserResolver().

Thanks

Recommend

  • Curl works, requests doesn't
  • Which API key for android GCM server
  • Can't remove inline event handler in chrome
  • How to test method of JavaFX controller?
  • How to “remove”/“change” some require(…) calls when using browserify?
  • Laravel S3 File Upload MimeType Issue
  • Extend Codeigniter Exceptions class to add a custom method
  • PHP Carbon “month()” method generates wrong DateTime
  • Laravel 5 how to include autoload.php
  • Aspect advising other aspects
  • Can't get LogCat (Alcatel OneTouch Evolve)
  • Defining variable by logical subseting on time interval in data.table
  • Partial specialization of a class template in derived class affects base class
  • Laravel at least one field is required
  • How to merge keras sequential models with same input?
  • hibernate sets dirty flag (and issues update) even though client did not change value
  • How can Delete be both a DDL and a DML statement
  • why xml file does not aligned properly after append the string in beginning and end of the file usin
  • htaccess add www if not subdomain, if subdomain remove www
  • Jackson Parser: ignore deserializing for type mismatch
  • JSON response opens as a file, but I can't access it with JavaScript
  • How to use remove-erase idiom for removing empty vectors in a vector?
  • Repeat a vertical line on every page in Report Builder / SSRS
  • Why is an OPTIONS request sent to the server?
  • Different response to non-authenticated users and AJAX calls
  • Why HTML5 Canvas with a larger size stretch a drawn line?
  • Spray.io: When (not) to use non-blocking route handling?
  • Accessing IRQ description array within a module and displaying action names
  • Modifying destination and filename of gulp-svg-sprite
  • GridView Sorting works once only
  • AT Commands to Send SMS not working in Windows 8.1
  • Is there a mandatory requirement to switch app.yaml?
  • File upload with ng-file-upload throwing error
  • ExecuteAsync RestSharp to allow backgroundWorker CancellationPending c#
  • AngularJs get employee from factory
  • Rails 2: use form_for to build a form covering multiple objects of the same class
  • Angular 2 constructor injection vs direct access
  • How do I configure my settings file to work with unit tests?
  • Is it possible to post an object from jquery to bottle.py?
  • Is there any way to bind data to data.frame by some index?