jordan.dobrev.88@gmail.com's avatar

Pass data from middleware to controllers

Hi everyone,

I am trying to implement Rest API with Authorizaion. Each user has to attach an api_key to each request and then my Rest.php middleware identifies him using database. I want to share that user record accross all my Rest controllers. I have a few ideas but i don't find any of them clear and easy.

Here is my Middleware so you can get the idea.

class Rest
{

    protected $repository;
    protected $event;

    public function __construct(EventRepository $repository)
    {
        $this->repository = $repository;
    }

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure                 $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (!$request->has('api_key')) {
            return response('Api key missing!', 401);
        }

        $this->event = $this->repository->findByApiKey($request->get('api_key'));

        if (!$this->event) {
            return response('Unauthorized.', 401);
        }

        return $next($request);
    }

    public function getEvent()
    {
        return $this->event;
    }
}

I want to be able to use $rest->getEvent() accross all my controllers, but unfortunatelly the middlewares are not registered as singletons. Any ideas?

0 likes
7 replies
pmall's avatar

I think you should do just the api_key presence verification in the middleware.

The authorization part should go in a form request (the authorization method is made for that). And by the way you may set the returned event as a form request attribute so it is accessible in the controller.

# RestFormRequest.php

public function authorize()
{
  $this->event = $this->repository->findByApiKey($this->api_key);

  return !is_null($this->event);
}
1 like
jordan.dobrev.88@gmail.com's avatar

That is true but it's a little bit unclear and messy for developers. What if a new developer comes in and has no idea that he has to use the form request?

I want the middleware to be executed on all routes, so even if a developer forgets to use the form request it will still work. That is the goal of the middleware right?

pmall's avatar

IMHO middleware focus is on the request/response handling, not dealing with the controller.

1 like
jordan.dobrev.88@gmail.com's avatar
Level 8

That does the trick for me:

In AppServiceProvider register() method register the middleware as a singleton:

$this->app->singleton('App\Http\Middleware\Rest');

And if you need the information for the user in any of the controllers use the Dependency Injection to get it.

5 likes
pmall's avatar

??? You didn't wanted to use dependency injection for the form request

jordan.dobrev.88@gmail.com's avatar

I did but the form request is only going to work when you inject it, and I wanted to get the $event object only when the functionality requires it.

Both do the same job, it's a personal choice what you want to use.

rawnato's avatar

I use so!

/**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request $request
     * @param  \Closure $next
     * @return mixed
     * @throws \Exception
     */
    public function handle($request, Closure $next)
    {
        if ($request->header('X-User-Domain') != '') {
            $User = User::whereDomain($request->header('X-User-Domain'))->whereConfirmed(true)->get();

            if ($User->count()) {
                Auth::login($User->first());

                return $next($request);
            }
        }

        return Response::json([
            'message' => 'Invalid Credentials.',
            'error' => true,
        ], 404);
    }

Please or to participate in this conversation.