I'm developing a small website to manage job offers and some news (as a blog, without commenting). As a stack, I'm using Laravel 10 + Vue 3 (Composition API).
I'm having a problem during authentication, because after logging in, any request (including those where you don't need to be logged in) fail.
I use Sanctum to be able to do this, with a custom guard to be able to use the admin table for this. Here is the configuration of those guards:
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'admins' => [
'driver' => 'eloquent',
'model' => App\Models\Administrator::class
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
As you can see, one of the providers refers to the Administrator model, where I use the document and password columns for login. This is the model in question:
<?php
namespace App\Models;
use Illuminate\Auth\Authenticatable;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Notifications\Notifiable;
/**
* App\Models\Administrator
*
* @property int $cod_Gestor
* @property string $dni_gestor
* @property string $nombre
* @property string $apellido1
* @property string|null $apellido2
* @property string $correo
* @property string $contrasenna
* @property int $baja_Cuenta
* @property int $id_Perfil
* @property string $fechaCreacion
* @property-read \Illuminate\Database\Eloquent\Collection<int, \App\Models\Article> $articles
* @property-read int|null $articles_count
* @method static \Illuminate\Database\Eloquent\Builder|Administrator newModelQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Administrator newQuery()
* @method static \Illuminate\Database\Eloquent\Builder|Administrator query()
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereApellido1($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereApellido2($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereBajaCuenta($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereCodGestor($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereContrasenna($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereCorreo($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereDniGestor($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereFechaCreacion($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereIdPerfil($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereNombre($value)
* @property int $id
* @property string $document
* @property string $name
* @property string $first_surname
* @property string|null $second_surname
* @property string $email
* @property string $password
* @property int $account_status
* @property string|null $created_at
* @property string|null $updated_at
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereAccountStatus($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereCreatedAt($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereDocument($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereEmail($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereFirstSurname($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereId($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereName($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator wherePassword($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereSecondSurname($value)
* @method static \Illuminate\Database\Eloquent\Builder|Administrator whereUpdatedAt($value)
* @property-read \Illuminate\Notifications\DatabaseNotificationCollection<int, \Illuminate\Notifications\DatabaseNotification> $notifications
* @property-read int|null $notifications_count
* @mixin \Eloquent
*/
class Administrator extends Model implements \Illuminate\Contracts\Auth\Authenticatable
{
use HasFactory, Authenticatable, Notifiable;
protected $table = 'administrators';
// protected string $username = 'document';
protected $guarded = [];
public function articles(): HasMany
{
return $this->hasMany(
Article::class,
'author',
);
}
}
The login logic is as follows:
<?php
namespace App\Http\Controllers;
use App\Exceptions\ApiException;
use App\Http\Resources\AdminResource;
use App\Models\Administrator;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Validator;
class LoginController extends Controller
{
/**
* Handle user login request.
*
* @param Request $request
*
* @return AdminResource
*
* @throws ApiException
*/
public function login(Request $request): AdminResource
{
$this->validateCredentials($request->all());
$guard = $request->guard;
if ($guard == 'admin') {
return $this->adminLogin($request->only('identity', 'password'), $guard);
}
throw new ApiException('Guard not supported', 400);
}
/**
* Validate user credentials.
*
* @param array $credentials
*
* @return void
*
* @throws ApiException
*/
private function validateCredentials(array $credentials): void
{
$validator = Validator::make($credentials, [
'identity' => 'required',
'password' => 'required',
'guard' => 'required'
]);
if ($validator->fails()) {
throw new ApiException('', 422);
}
}
/**
* Authenticate admin user.
*
* @param array $credentials
* @param string $guard
*
* @return AdminResource
*
* @throws ApiException
*/
private function adminLogin(array $credentials, string $guard): AdminResource
{
$credentials['document'] = $credentials['identity'];
unset($credentials['identity']);
if (!Administrator::whereDocument($credentials['document'])->exists()) {
throw new ApiException("Admin not exists", 404);
}
if (Auth::guard($guard)->once($credentials)) {
Auth::login(Auth::guard($guard)->user());
return new AdminResource(Auth::user());
} else {
throw new ApiException("Invalid credentials", 401);
}
}
/**
* Handle user logout request.
*
* @return void
*/
public function logout(): void
{
Auth::logout();
}
}
As you can see, if the parameter $guard is equal to 'admin', the function adminLogin is called, where, using the Auth::once function, the credentials provided are checked, and if everything is OK, the Auth::login method is called and the authenticated user is returned.
So far so good. However, after this, when returning to the home screen, any request fails with a status error 500, where the message indicates that the users table does not exist, when at no time I make use of this table.
I would like to know if anyone has encountered this problem at any time.
Any ideas or solutions are welcome. Thanks, and best regards.
I have tried to change the guard or change the auth method to attempt one, but this doesn't work.