jdforsythe's avatar

Using Authorization Gate in Lumen

The documentation section on Authorization is pretty lacking for Lumen. It says to refer the the full Laravel documentation, which I've read several times. So I want to start with step one, make a single ability and test it.

The docs say the "primary difference when using authorization in Lumen compared to Laravel is... you may simply use the Gate facade in your AuthServiceProvider to define abilities". Firstly, I have facades disabled because I've been able to do everything else without them, and I'd rather not enable them for this one feature. Anyway... you can't "simply" use the Gate facade.

Even if I enable facades, I get:

Class 'App\Providers\Gate' not found

I tried:

Use Illuminate\Contracts\Auth\Access\Gate;

Which yields

Non-static method Illuminate\Contracts\Auth\Access\Gate::define() cannot be called statically...

Right. The Laravel docs show it injected into the boot method. Lumen doesn't do that.

use Illuminate\Contracts\Auth\Access\Gate as GateContract;
...
public function boot(GateContract $gate) {
}

Yields:

Argument 1 passed to App\Providers\AuthServiceProvider::boot() must be an instance of Illuminate\Contracts\Auth\Access\Gate, none given

If it's so simple, can someone tell me what I'm missing here?

0 likes
4 replies
jdforsythe's avatar

I got maybe a little closer...

public function boot() {
  $this->app['gate']->define('test', function($user, $test) { return true; });
}
FatalErrorException...
Call to undefined method Illuminate\Support\Facades\Gate::define()
Connor-S-Parks's avatar
use Illuminate\Contracts\Auth\Access\Gate;
public function boot()
{
    // ...
    $this->app[Gate::class]->define('test', function ($user, $test) { return true; });
    // ...
}
jdforsythe's avatar

Thank you sir! I got it to work a different way:

use Illuminate\Support\Facades\Gate;
...
Gate::policy();

But I like your way more.

Now I'm having a different issue - the gate policy is working fine, but when the user is unauthorized it throws Illuminate\Auth\Access\AuthorizationException which dumps out a JSON object with the stack and whatnot - but the status code is unexpectedly 500 instead of 403.

I figure that's odd, but I can just catch it in the Exceptions\Handler.php. But for some reason the render() method never seems to run on this exception. I've tried this:

public function report(Exception $e) {
  dd($e);
}

which sends the pretty xdebug output, as expected. However,

public function render($request, Exception $e) {
  dd($e);
}

never executes and I still get the same JSON error output as before. Any idea why this isn't executing the render() function or how I can otherwise globally configure the $this->authorizeForUser() controller method to return a 403 on an error?

jdforsythe's avatar

Got it. Dingo was intercepting the error. Just needed to add a Dingo handler.

Please or to participate in this conversation.