Search code examples
laravellaravel-5.6policy

policy returns This action is unauthorized no matter what


i am just trying to show a company to anyone who ants to see it authServiceProvider:

        Company::class => CompanyPolicy::class ,
'App\Models\Company' => 'App\Policies\CompanyPolicy',

companyPolicy

 public function view( Company $company)
{

    return true ;
}

companyController

 public function __construct(CompanyRepository $companies)
{
    $this->companies = $companies;
}


public function show(Company $company)
{
    $this->authorize('view', $company);

    return $this->companyRepository->show($company);
}

route to controller:

Route::apiResource('companies', 'CompanyController');

it always return This action is unauthorized. why?


Solution

  • The line of Company::class => CompanyPolicy::class, is redundant in your AuthServiceProvier and you have to remove it.

    let me bring an example:

    assume we have a model named SomeModel and have registered its policy. the policy has the method of view which check current user is able to call show method.

    For Guard of api you may create a trait like below:

    trait ApiTrait
    {
        /**
         * Authorize a given action for the current user.
         *
         * @param  mixed $ability
         * @param  mixed|array $arguments
         * @return \Illuminate\Auth\Access\Response
         *
         * @throws \Illuminate\Auth\Access\AuthorizationException
         */
        public function authorizeApi($ability, $arguments)
        {
            if (!request()->user('api')->can($ability, $arguments)) {
                abort(403, 'This action is unauthorized.');
            }
        }
    }
    

    then in your controller use it:

    class ExampleController extends Controller
    {
        use ApiTrait;
    
        public function show(SomeModel $something)
        {
            $this->authorize('view', $something);
    
            return 'it workes';
        }
    }
    

    pay attention you should protect your route with middleware of auth:api or else you will get error code 500 when calling the can method in ApiTrait.