mardi 25 juillet 2017

Use multiple Auth guards for one Policy

I have implemented multiple Auth guards in a Laravel 5.4 project (one of for admins and the other for regular users). This has worked successfully so far and both admins and users are able to log in. I am now trying to implement a Policy class that works for both Auth guards. This is because I have certain models that I want all administrators to edit and only users who own the model to be able to edit. So I have defined a policy with this method.

App\Policies\ModelPolicy

public function update(User $user, Model $model)
{
    if ($user->id === $model->user_id) {
        return true;
    }

    if (Auth::guard('admin')->check()) {
        return true;
    }

    return false;
}

Then in whatever controller method I have for my model:

App\Http\Controllers\ModelController

public function update(Model $model)
{
    $this->authorize('update', $model);

    // update model
}

This works perfectly if a regular user is logged in. However, when an admin user is logged in, it doesn't even reach the policy (I know this from error logging). I am guessing that the Policy class does something to automatically deny a request if the default guard in Auth::check() fails. However, since it is valid for my users to have one of several guards (not just the default), I need to bypass this behavior.

I know I could implement the admin logic in my controller method and only use the policy if I know I am dealing with a non-admin:

public function update(Model $model)
{
    if (!Auth::guard('admin')->check()) {
        $this->authorize('update', $model);
    }

    // update model
}

However, this can quickly spiral out of control if my admin condition is more complicated than simply being logged in. More importantly, all of this logic belongs in a Policy, not muddying up my controller.

How is it possible to use the same Policy class for multiple authentication guards?



via Chebli Mohamed

Aucun commentaire:

Enregistrer un commentaire