Search code examples
phplaravellaravel-5laravel-5.3

Gate::allows not working in Laravel 5.3


I have a problem on Laravel 5.3 with the new Gate::allows method.

Here is my AuthServiceProvider.php for the test:

<?php

namespace App\Providers;

use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;

class AuthServiceProvider extends ServiceProvider
{
  /**
   * The policy mappings for the application.
   *
   * @var array
   */
  protected $policies = [
      'App\Model' => 'App\Policies\ModelPolicy',
  ];

  /**
   * Register any authentication / authorization services.
   *
   * @return void
   */
  public function boot()
  {
      $this->registerPolicies();

      Gate::define('settings', function ($user)
      {
          return true;
      });
  }
}

Normally, whatever the user's role, everybody can access the settings.

But this always display 'no' instead of 'ok'.

<?php

namespace App\Http\Controllers;

use Gate;
use Illuminate\Http\Request;

use App\Http\Requests;
use App\Http\Controllers\Controller;

class SettingsController extends Controller
{
  public function __construct(Request $request)
  {
    echo Gate::allows('settings') ? 'ok' : 'no';
  }
}

Solution

  • From Laravel 5.3 we can't access session or the authenticated user in controllers constructors, as stated in the upgrade guide

    Since the Gate facades uses the Usermodel, probably it tries to access the user but it's not still ready in the constructor of your controller

    So, you should consider using a middleware to check the Gate. You can also use a Closure based middleware directly in the controller constructor:

    public function __construct(Request $request)
    {
        $this->middleware(function ($request, $next) {
            echo Gate::allows('settings') ? 'ok' : 'no';
        });
    }