I have a user model class that has class User extends Authenticatable and another model class that I also created that has class Foo extends Model
it's causing some issues in displaying data from the routes files and I am pretty sure it has something to do with the 'Authenticatable' part because for Foo, the information displays correctly, but for User, it doesn't, even with the same code.
What's the difference between these two classes/models?
If you look at the imports it shows:
use Illuminate\Foundation\Auth\User as Authenticatable;
This means Authenticatable is an alias to Illuminate\Foundation\Auth\User.
If you look into the source code of Illuminate\Foundation\Auth\User it shows:
class User extends Model implements
AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
}
Basically Authenticatable is the same as a normal model, but adds the following traits:
Authenticatable
Authorizable
CanResetPassword
MustVerifyEmail
Illuminate\Auth\Authenticatable
This is used by authentication, and adds the following methods:
getAuthIdentifierName()
getAuthIdentifier()
getAuthPassword()
getRememberToken()
setRememberToken()
getRememberTokenName()
Illuminate\Foundation\Auth\Access\Authorizable
This is used to determine if a User is able to perform certain abilities. It has the following methods:
can()
canAny()
cant()
cannot()
Illuminate\Auth\Passwords\CanResetPassword
Used for resetting passwords. It has the following methods
getEmailForPasswordReset()
sendPasswordResetNotification()
Illuminate\Auth\MustVerifyEmail
Used for verifying emails if your using that feature. It has the following methods:
hasVerifiedEmail()
markEmailAsVerified()
sendEmailVerificationNotification()
getEmailForVerification()
I recommend try having a look at the source code yourself to get a better understanding what these traits do.
Also, based on the above, I doubt it will have any issues with your data in the route files.
When you extend the Authenticatable, you are getting more features like authentication and authorization and registering stuff. So whenever you have users or customers or accounts refer to persons, it's good to create a new model that extends the Authenticatable.
When you extend just the Model, you are creating a class or type just as a reflection of some kind of resource you have in your application.
Try to locate the definition of the Authenticatable and you will see:
The Illuminate\Foundation\Auth\User as Authenticatable is just a class that tacks on some additional traits Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail.
The underlying Illuminate\Foundation\Auth\User class also extends model giving you all the relational functionality you would expect if you were to simply extend Model.
class User extends Model implements
AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword, MustVerifyEmail;
}
Related
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)?
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
User.php
namespace App;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
protected $fillable = ['name','email','password'];
}
Error occurs when attempting to login in Laravel.
Error:
Argument 1 passed to Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Contracts\Auth\Authenticatable, instance of App\User given, called in F:\eStore\vendor\laravel\framework\src\Illuminate\Auth\SessionGuard.php on line 385
You need to add implements \Illuminate\Contracts\Auth\Authenticatable to your User model class definition.
class User extends Model implements \Illuminate\Contracts\Auth\Authenticatable {
}
I migrate from laravel 4 to laravel 5. I modified User Model to make it compatible to laravel 5 User Model. The User model in Laravel 4 is like that:
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
// some model relation functions..
...
public function getLocationId()
{
return $this->location_id;
}
}
I modified it and the new User model is like that now:
namespace App\Models;
use Illuminate\Auth\Authenticatable;
use Illuminate\Auth\Passwords\CanResetPassword;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
use Illuminate\Database\Eloquent\Model as Eloquent;
class User extends Eloquent implements AuthenticatableContract, CanResetPasswordContract {
use Authenticatable, CanResetPassword;
// some model relation functions (some changes for namespace)
...
public function getLocationId()
{
return $this->location_id;
}
}
However, getLocationId method is now problematic. The following line results in an error.
$auth_location_id = Auth::user()->getLocationId();
This is the error:
BadMethodCallException in Builder.php line 2508:
Call to undefined method Illuminate\Database\Query\Builder::getLocationId()
How can I make the method compatible to laravel 5? Thanks..
Update:
$auth_location_id = Auth::user()->getLocationId; works but returns empty!!
The line below works properly.
$auth_user_id = Auth::user()->getAuthIdentifier();
By my understanding, and short experience with Laravel, all I do is just to use:
use Illuminate\Foundation\Auth\User as Authenticatable;
Then have my Model as:
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
public function getLocationId()
{
return $this->location_id;
}
}
So I may be safe to assume, at least because it works for me that all those contracts has be extended in the facade called when ....\User is used.
PS: this is just an illustration of how I currently use it in Laravel 5.2.*.
Hope this can help or lead you to the solution :)
I saw this error for the first time and don't really know what to do about it.
When I tried to register a new user on my website and when I clicked on submit button it shows:
FatalErrorException in User.php line 11:
Class App\User contains 6 abstract methods and must therefore be declared abstract or implement the remaining methods (Illuminate\Contracts\Auth\Authenticatable::getAuthIdentifierName, Illuminate\Contracts\Auth\Authenticatable::getAuthIdentifier, Illuminate\Contracts\Auth\Authenticatable::getAuthPassword, ...)
User Model:
<?php
namespace App;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Model;
class User extends Model implements Authenticatable
{
protected $table = 'users';
protected $primaryKey = 'id';
}
What is it trying to say, I don't understand. Please can someone help me with this?
You are implementing Illuminate\Contracts\Auth\Authenticatable. This is interface and requires your User class to have some required methods:
public function getAuthIdentifierName();
public function getAuthIdentifier();
public function getAuthPassword();
public function getRememberToken();
public function setRememberToken($value);
public function getRememberTokenName();
If you are trying to make default User model, you should use Illuminate\Foundation\Auth\User as Authenticatable and extend it instead of Model class. There is no need to implement Authenticatable interfase.
You need to either extend Illuminate\Foundation\Auth\User instead of Illuminate\Database\Eloquent\Model, or use Illuminate\Auth\Authenticatable trait in your class
UPDATE
You need to extend Illuminate\Foundation\Auth\User like this
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
}
UPDATE 2
Also make sure you don't have native Laravel's App\User model in you app folder, named User.php
I'm trying to use the Versionable Package in my Laravel 4 app based on the new, trait based implementation like this
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
namespace MyApp\Models;
class User extends Eloquent implements UserInterface, RemindableInterface {
use Venturecraft\Revisionable\Revisionable;
...
When i use this code above, I get this error
Class 'MyApp\Models\Eloquent' not found
I have also tried changing the namespace to app\models but it still shows the not found error.
Please could someone help me out here? I followed all the instructions on the Github page but as I'm new to Laravel, I may be missing something.
You could use either of the following solutions:
Change your class declaration to:
class User extends \Eloquent implements \UserInterface, \RemindableInterface
Or, simply remove the line:
namespace MyApp\Models;
I would recommend taking the second solution (removing the namespace) for now, until you are comfortable with namespaces in PHP.
Additionally, you should be using RevisionableTrait, not Revisionable, e.g.,
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use Venturecraft\Revisionable\RevisionableTrait;
You must write fully qualified name for Eloquent
class User extends \Eloquent implements UserInterface, RemindableInterface