Search code examples
phplaravelauthorizationlaravel-passportpolicy

Laravel Policies in API always 403 unauthorized


I tried to authorize users in userController using Policies. I followed documentations and some tutorials and it doesn't seem to work anyways.

api.php

Route::resource('users', 'User\UserController', ['except' => ['create', 'edit']]);

UserController.php

namespace App\Http\Controllers\User;

use App\Http\Controllers\ApiController;
use Illuminate\Http\Request;
use App\User;
use App\Mail\UserCreated;
use App\Mail\UserEmailUpdated;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
class UserController extends ApiController
{
  public function __construct()
  {
    $this->middleware('can:view,user')->only('show');
    //$this->middleware('can:update,user')->only('update');
    //$this->middleware('can:delete,user')->only('destroy');
  }

    public function show(User $user)
    {
        //$this->authorize('view', $user);
        return $this->showOne($user);
    }

UserPolicy.php

namespace App\Policies;

use App\User;
use App\Traits\AdminPolicyTrait;
use Illuminate\Auth\Access\HandlesAuthorization;

class UserPolicy
{
    use HandlesAuthorization;

    public function view(User $user, User $model)
    {
        //return $user->id === $model->id
        return true;
    }
}

AuthServiceProvider.php

namespace App\Providers;

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

class AuthServiceProvider extends ServiceProvider
{

    protected $policies = [
        App\User::class => App\Policies\UserPolicy::class,
    ];

    public function boot()
    {
        $this->registerPolicies();
    }
}

Neither $this->middleware nor $this->authorize works. If I remove policy authorization from the controller, everything works fine. Also, I'm passing Personal Access token from Passport in the request and it works fine too. If I intentionally make a typo in the Policy file, the error gets thrown so the policy seems to be connected to the controller properly.


Solution

  • You are most likely referencing the wrong classes there. The namespace for AutheServiceProvider is declared as App\Providers. Unless otherwise aliased all references (that are not Fully Qualified Class Names) are referenced from this namespace that is declared.

    App\User::class     would be   'App\Providers\App\User'
    

    You will need to alias the App namespace, alias these classes or use their FQCN.

    use App;
    ...
    App\User::class
    

    Or

    use App\User;
    ...
    User::class
    

    Or

    \App\User::class
    

    Or - less preferred (use the string for the FQCN)

    'App\User'