-1

On the one hand, I have an Eloquent model User that extends Illuminate\Database\Eloquent\Model. On the other hand, I have SanctumUser extends Authenticatable (https://laravel.com/docs/8.x/sanctum#issuing-api-tokens).

What I would like to do is, User extends Model, SanctumUser, but multiple inheritance is not possible in PHP 7.x.

I know that some traits are used in SanctumUser according to the documentation I've linked above. These traits are: use HasApiTokens, HasFactory, Notifiable;. Do you know if they are sufficient if I remove extends Authenticatable and replace it with extends Model (User would extend SanctumUser)?

Karl Hill
  • 12,937
  • 5
  • 58
  • 95
JarsOfJam-Scheduler
  • 2,809
  • 3
  • 31
  • 70

1 Answers1

3

Authenticable as alias for Illuminate\Foundation\Auth\User class has traits which has methods for authentication and authorization

<?php

namespace Illuminate\Foundation\Auth;

use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\MustVerifyEmail;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Access\Authorizable as AuthorizableContract;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\Authorizable;

class User extends Model implements
    AuthenticatableContract,
    AuthorizableContract,
    CanResetPasswordContract
{
    use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
}

Even the default User model class which is available with any new standard Laravel installation has it extending the Authenticable class [use Illuminate\Foundation\Auth\User as Authenticatable;]

Default User Model class in a standard Laravel application has two more traits - Notifiable and HasFactory (since Laravel 8.x)

<?php

namespace App\Models;

use Illuminate\Notifications\Notifiable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use HasFactory;
    use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name',
        'email',
        'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
        'remember_token',
        'two_factor_recovery_codes',
        'two_factor_secret',
    ];
}

With Sanctum you may add trait HasApiToken to the User model class.

In order to easily integrate Laravel Sanctum or Jetstream or Laravel UI or Breeze for authentication and authorization to your app, its better to make User class extend Authenticable - plug and play

Donkarnash
  • 12,433
  • 5
  • 26
  • 37
  • As `User extends Illuminate\Database\Eloquent\Model`, I don't think it extends `Authenticatable`. So I should add this extension no? in one way or another – JarsOfJam-Scheduler Dec 18 '20 at 09:44
  • 1
    Since `Authenticatable` here is actually an alias of `Illuminate\Foundation\Auth\User` that already extends `Model` and is the Laravel boilerplate User model so no need to extend `Model` yourself since it's already extended. However from your question it's not clear if you're extending the same `Authenticatable` class – apokryfos Dec 18 '20 at 09:50
  • 1
    Authenticable which is an alias for **Illuminate\Foundation\Auth\User** is already extending **Illuminate\Database\Eloquent\Model** So when you extend your **App\Models\User** from Authenticable it already has been extending Illuminate\Database\Eloquent\Model class via Authenticable – Donkarnash Dec 18 '20 at 09:56
  • "Authenticable which is an alias for Illuminate\Foundation\Auth\User is already extending Illuminate\Database\Eloquent\Model" => Did you mean that `Illuminate\Database\Eloquent\Model` extends `Authenticable`? – JarsOfJam-Scheduler Dec 18 '20 at 10:15
  • 1
    **NO**. The class `Illuminate\Foundation\Auth\User` extends `Illuminate\Database\Eloquent\User` class and the project's **User** model at `App\Models\User` extends **Illuminate\Foundation\Auth\User aliased as Authenticable** in the use statement – Donkarnash Dec 18 '20 at 10:15
  • Thank you. Well... my `App\Models\User` actually extends `Illuminate\Database\Eloquent\Model`, not `Illuminate\Database\Eloquent\User` so it won't work. I need to think about it, but ty. – JarsOfJam-Scheduler Dec 18 '20 at 10:40
  • @Donkarnash how do you know that Illuminate\Foundation\Auth\User is aliased as Authenticable? – JarsOfJam-Scheduler Dec 18 '20 at 10:45
  • 1
    Sorry that's a typo in the earlier comment **Illuminate\Foundation\Auth\User** aliased as **Authenticable** extends **Illuminate\Database\Eloquent\Model** and `App\Models\User` extends **Authenticable** – Donkarnash Dec 18 '20 at 10:46
  • 1
    See the second block of code in the answer - it's the default **User** class with standard Laravel install. Since the class is named User it can't extend another class named User so in the use statement Illuminate\Foundation\Auth\User is aliased as Authenticable – Donkarnash Dec 18 '20 at 10:48
  • Ah ok you mean it has a trait = an alias – JarsOfJam-Scheduler Dec 18 '20 at 10:57
  • ty very much, Sir. :-) I've followed your explanations. As I don't use the default `Model` class but my own (`WordpressMigrateModel extends Illuminate\Database\Eloquent\Model`), I have written and will test: `class MyOwnEloquentModelUser extends SanctumUser` ; `SanctumUser extends App\Foundation\Auth\User (the override of Auth\User which is an alias for Authenticable)` and finally `class App\Foundation\Auth\User extends WordpressMigrateModel` (which is the override of `Model`). – JarsOfJam-Scheduler Dec 18 '20 at 11:10