Babaktrad
Babaktrad

Reputation: 184

Authorization methods only works for default guard in Laravel

I'm using Laravel 5.5 and I'm trying to use Gate facade to allow admins to access resources like users. First, I define a gate in AuthServiceProvider.php like following:

Gate::define('view-users', 'App\Policies\UserPolicy@view');

Then, I write view method in Policy class like this:

public function view(Admin $admin, User $user)
{
    return true;
}

And, I apply the authorization like following:

//UsersController.php

$user = User::first();
if (Gate::allows('view-users', $user)) {
    $users = User::all();
    return view('admin.users.list', compact('users'));
}
return abort(403);

I note that, the $user argument is useless variable and I don't need it to perform authorization. By the way, when I use allows() method of Gate facade, it always returns false. While, when I use denies() instead, these steps work fine.

what's wrong with allows() method?!

However, corresponding to the Laravel Docs, I tested other ways to apply authorization via middleware(), Model or authorize(). But, I got the same result.

Edit: I should note that I'm using custom guard named web_admin

Thanks for any help.

Upvotes: 2

Views: 1793

Answers (1)

Hafez Divandari
Hafez Divandari

Reputation: 9029

Change your policy method to this:

public function view(User $user)
{
    return $user->isAdmin;
}

The first argument of the policy method is always the current authenticated user. Note that you are not required to pass the currently authenticated user to these methods. Laravel will automatically take care of passing the user into the gate Closure:

if (Gate::allows('view-users')) {
    // The current user can view all users...
}

If you want to check if the current user can update a specific user your policy method would be:

public function update(User $authenticatedUser, User $beeingEditedUser)
{
    return $authenticatedUser->isAdmin;
}

Then authorize like this:

if (Gate::allows('update-user', $beeingEditedUser)) {
    // The current user can update the user...
}

If you're using custom guard (according to your comment), you may have 2 options:

  1. Use forUser method:
use Illuminate\Support\Facades\Auth;

if (Gate::forUser(Auth::guard('web_admin')->user())->allows('view-users')) {
    // The current user can view all users...
}
  1. Protecting the routes, specifying the guard:
Route::middleware('auth:web_admin')->group(function () {
    Route::get('/users', 'UserController@index');
});

This causes Larvel to set your default auth driver and resolve the auth user based on your custom guard.

Upvotes: 1

Related Questions