laravellaravel-permission

Call to undefined method Auth::user()->can() in laravel 8 error


I have a problem with determining the permission with Auth::user()->can(). For example Auth::user()->can('trunk.index) returns always error;

But I have a problem. If I dump $user->getPermissionsViaRoles(); ,I will get a large result.

I'm using different table user_view table. And according to it I have changed in Auth.php file. and login is working fine.

'providers' => [
        'users' => [
            'driver' => 'self-eloquent',
            'model' => App\Models\UserView::class,
        ]
    ], 

But when I try to check permission the via Auth::user()->can('trunk.index) then it gives error below error.

Call to undefined method App\\Models\\UserView::can()

Below is my UserView model code.

<?php

namespace App\Models;

use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Support\Facades\Hash;
use Spatie\Permission\Traits\HasRoles;
use Laravel\Lumen\Auth\Authorizable;
use Laravel\Sanctum\HasApiTokens; 

class UserView extends Model implements AuthenticatableContract
{
    use Authenticatable;
    use HasFactory;
    use HasRoles;
    use HasApiTokens;
    protected $table = 'user_view';
    protected $primaryKey = "user_id";

    protected $fillable = [
        'username', 'password',
    ];

    protected $guarded = [];

    public function getAuthPassword()
    {
        return ['password' => $this->attributes['user_password']];
    }

    // public function can($abilities, $arguments = []) {
        
    // }

}

help me if I'm missing something. Thank you.


Solution

  • You are using a custom User model which does not implement the \Illuminate\Contracts\Auth\Access\Authorizable interface and \Illuminate\Contracts\Auth\Access\Gate\Authorizable trait. You do actually have an import for this interface, but it is not used anywhere.

    Also be careful about the existing import Laravel\Lumen\Auth\Authorizable. I'm not familiar with Lumen, but this might be a different implementation / wrong import.


    You essentially need to update your model with the following two lines:

    <?php
    
    namespace App\Models;
    
    use Illuminate\Auth\Authenticatable;
    use Illuminate\Database\Eloquent\Factories\HasFactory;
    use Illuminate\Database\Eloquent\Model;
    use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
    use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
    use Illuminate\Foundation\Auth\Access\Authorizable;             // <-- add import
    use Spatie\Permission\Traits\HasRoles;
    use Laravel\Sanctum\HasApiTokens; 
    
    class UserView extends Model implements AuthenticatableContract,
                                            AuthorizableContract    // <-- add interface
    {
        use Authenticatable;
        use Authorizable;                                           // <-- add trait
        use HasFactory;
        use HasRoles;
        use HasApiTokens;
    
        // ... other code ...
    }