Run Middleware Before Controller's Constructor On Laravel 5.1?
Asked Answered
T

2

8

I have a middleware that authenticates a JWT user using tymon/jwt-auth package:

public function handle($request, \Closure $next)
{
    if (! $token = $this->auth->setRequest($request)->getToken()) {
        return $this->respond('tymon.jwt.absent', 'token_not_provided', 400);
    }

    try {
        $user = $this->auth->authenticate($token);
    } catch (TokenExpiredException $e) {
        return $this->respond('tymon.jwt.expired', 'token_expired', $e->getStatusCode(), [$e]);
    } catch (JWTException $e) {
        return $this->respond('tymon.jwt.invalid', 'token_invalid', $e->getStatusCode(), [$e]);
    }

    if (! $user) {
        return $this->respond('tymon.jwt.user_not_found', 'user_not_found', 404);
    }

    $this->events->fire('tymon.jwt.valid', $user);

    return $next($request);
}

Then I have a controller and I want to pass the user from the middleware to the controller.

So I did on the controller:

public function __construct()
{
    $this->user = \Auth::user();
}

The problem is that $this->user is null, but when I do this on a method of the controller, it's not null.

So:

public function __construct()
{
    $this->user = \Auth::user();
}

public function index()
{
    var_dump($this->user); // null
    var_dump(\Auth::user()); // OK, not null
}

So the issue is that __construct is running before the middleware. How can I change that, or do you have another solution?

Update: I'm using dingo/api for routing, maybe it's an error on their side?

Tran answered 13/4, 2016 at 19:11 Comment(4)
You cannot do that. You have think about how to pass that user from middleware (not from controller).Akin
@Akin Even when I pass the $user parameter like that: $request->attributes->add(compact('user')); I get the same result on the controller, because the constructor runs before the middleware. (probably dingo/api error)Tran
Was this solved ? i am curious to know what you did.Harris
Did you ever solve this? I have the same problem (using Sentinel)Plantation
G
1

You should use the middleware(s) in the routes

Route::middleware('jwt.auth')->group(function() {
// your routes 
});
Gradey answered 19/6, 2020 at 17:20 Comment(0)
A
0

1) Remove Your middleware from Your kernel's $middleware array

2) Put Your middleware to $routeMiddleware array with custom name jwt.auth:

protected $routeMiddleware = [
    // ...
    'jwt.auth' => 'App\Http\Middleware\YourAuthMiddleware'
];

2) Create BaseController in parent directory of needle controller, with function:

public function __construct() {
    $this->middleware('jwt.auth');
}

3) Extend needle controller from BaseController

4) Make __construct function of needle controller to look like this:

public function __construct() {
    parent::__construct();
    $this->user = \Auth::user();
}
Akin answered 13/4, 2016 at 19:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.