Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

hassanshahzadaheer's avatar

This action is unauthorized. for all user except user have id of 2

Hi!

I am stuck to understand why the code does not allow performing curd action except the superuser. I try my best to solve this problem google it but still not got the point.

my ProjectsController.php file

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Project;
use App\Mail\ProjectCreated;
class ProjectsController extends Controller
{
  public function __construct()
  {
    $this->middleware('auth');
  }
  public function index()
  {
    $projects = auth()->user()->projects;
    return view('projects.index',['projects' => $projects]);
  }

  public function create()
  {
    return view('projects.create');
  }

  public function store()
  {
    $attribute = $this->validateProject();
    $attribute['owner_id'] = auth()->id();
    Project::create($attribute);

    // \Mail::to('[email protected]')->send(
    //   new ProjectCreated($project)
    // );

    return redirect('/projects');
  }

  public function show(Project $project)
  {
    $this->authorize('update',$project);
    // if($project->owner_id !== auth()->id()){
    //   abort(403);
    // }
    return view('projects.show',['projects' => $project]);
  }

  public function edit(Project $project)
  {

    return view('projects.edit',['projects' => $project]);
  }

  public function update(Project $project)
  {
    
    $project->update($this->validateProject());
    return  redirect('/projects');
  }

  public function destroy(Project $project )
  {

     $project->delete();
     return  redirect('/projects');

  }
  public function validateProject()
  {
    return $attribute = request()->validate([
          'title' => ['required','min:3'],
          'description' => ['required','min:3']
      ]);
  }
}

AuthServiceProvider.php

<?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\Project' => 'App\Policies\ProjectPolicy',
    ];

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
        Gate::before(function ($user){
            return $user->id == 2;
        });
    }
}

web.php

0 likes
27 replies
mstrauss's avatar

DISREGARD, your original Gate policy actually seems fine...

It's likely this causing your issue:

        $this->registerPolicies();
        Gate::before(function ($user){
            return $user->id == 2;
        });

Traditionally it would look more like:

Gate::define('project', function ($user, $project) {
        return $user->id == $project->user_id;
    });

And for the super user:

Gate::before(function ($user, $ability) {
    if ($user->id == 2) {
        return true;
    }
});
1 like
a10d's avatar

Hi It seems like your problem is in the AuthServiceProvider

Before every gate check, you are checking if the user has the id of 2. If not, you are returning false, so the check fails. When a check returns false, the permission is not given and no further checks will be made.

A solution would be to only return true if the id matches:

...
    public function boot()
    {
        $this->registerPolicies();
        Gate::before(function ($user){
            if (user->id == 2) {
                return true;
            }
        });
    }
...

You can find more info in the documentation: https://laravel.com/docs/5.8/authorization#gates

1 like
mstrauss's avatar

What does your App\Policies\ProjectPolicy' look like?

hassanshahzadaheer's avatar

Hi! thank you so much but I already try this solution and it shows the same error.

but one thing please clear that where I put this line of code

Gate::define('project', function ($user, $project) {
        return $user->id == $project->user_id;
    });

and what does this variable do

$ability
hassanshahzadaheer's avatar

Here it is my dear

<?php

namespace App\Policies;

use App\User;
use App\Project;
use Illuminate\Auth\Access\HandlesAuthorization;

class ProjectPolicy
{
    use HandlesAuthorization;
    /**
     * Determine whether the user can view the project.
     *
     * @param  \App\User  $user
     * @param  \App\Project  $project
     * @return mixed
     */
    public function update(User $user, Project $project)
    {
        return $project->owner_id == $user->id;
    }
}

and for once I try this

return $project->owner_id == $user->id;

inside all these function

viewAny
create
delete
restore
forceDelete

thank you so much

mstrauss's avatar

Try removing this trait:

use HandlesAuthorization;
mstrauss's avatar

You don't need to define the 'project` gate method, since you are handling it with a policy, which makes more sense in a CRUD situation with a defined model.

$ability is just a stand in for the action i.e. Gate::define('update-post', 'App\Policies\PostPolicy@update');

mstrauss's avatar

Please share how you are using the ProjectPolicy.

hassanshahzadaheer's avatar

sorry I am totally new to laravel that's why I am not able to work more effectively

<?php

namespace App\Policies;

use App\User;
use App\Project;
use Illuminate\Auth\Access\HandlesAuthorization;

class ProjectPolicy
{
    use HandlesAuthorization;


    /**
     * Determine whether the user can view the project.
     *
     * @param  \App\User  $user
     * @param  \App\Project  $project
     * @return mixed
     */
    public function update(User $user, Project $project)
    {
        return $project->owner_id == $user->id;
    }


}

thank you so much I appreciate you help

mstrauss's avatar

Okay, so let's try this:

// first just return true on the policy to see if the issue is the comparison of the user id and the project owner id.


    /**
     * Determine whether the user can view the project.
     *
     * @param  \App\User  $user
     * @param  \App\Project  $project
     * @return mixed
     */
    public function update(User $user, Project $project)
    {
        return true; // $project->owner_id == $user->id;
    }

If the $user is able to view the project after doing this, then check in your local DB to make sure that the auth user's ID and the project ID you are trying to access are ==.

munazzil's avatar

In your auth service provider remove below one there having the user->id two,

   $this->registerPolicies();
    Gate::before(function ($user){
        return $user->id == 2;
    });
hassanshahzadaheer's avatar

like this ?

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

        $gate->before(function ($user) {
            return $user->id;
        });
    }
pedroroccon's avatar

@ Like this:

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

Just remove the Gate::before from boot() method, inside the AuthServiceProvider class. This condition is telling to application that only user with ID 2 can do the action.

munazzil's avatar
munazzil
Best Answer
Level 13

Something like below,

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

    $gate->before(function ($user) {
        return $user->id = Auth::user()->id;
    });
    }
subashc069's avatar

This did the trick for me

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

    $gate->before(function ($user) { 
        if( $user->id == 1 ){   //check if the user is admin
            return true;
       }
    });
}
ZenSurfer's avatar

@schmedii great answer! small typo. In "if" statement, use: $user now my app is working perfectly :)

Please or to participate in this conversation.