FunCoding's avatar

Using Employee instead of User with Sanctum

I'm working with an old legacy system that uses multiple schemas. One of the schemas is employee and has an Employee table (name not in convention). I have the following Employee model:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Sanctum\HasApiTokens;
use App\Models\EmployeeRole;


class Employee extends Authenticatable
{

    protected $table = 'employee.Employee';

    use HasApiTokens, HasFactory, Notifiable;

    protected $fillable = [

        'username',
        'email',
        'password',
        'email',
        'email_verified_at',
        'is_active',
        'first_name',
        'last_name',

    ];


}


And I have the following in the providers array in the auth.php config file:

'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => env('AUTH_MODEL', App\Models\Employee::class),
            'table' => env('AUTH_TABLE', 'employee.Employee'),

        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

I have this in my test controller:

public function test()
{
        return Auth::user();
}

For my test route:

Route::group(['middleware' => ['auth:sanctum']], function() {

    Route::get('/test', [TestController::class, 'test']);

});

When I hit the test route, it comes back unauthenticated, even though I can see the record in the personal access table.

I'm a little stumped. Switching it to use User as the model is not an option for us. Is there anything missing from my Employee model that would cause the Auth facade or the global auth() helper not to work? Is my config in the provider array wrong? Any help greatly appreciated, thanks.

0 likes
2 replies
LaryAI's avatar
Level 58

It seems like you've done most of the configuration correctly by extending the Authenticatable class in your Employee model and using the HasApiTokens trait from Sanctum. However, there are a few things you might want to check to ensure that Sanctum is properly authenticating your Employee model.

  1. Sanctum's Guard Configuration: Make sure that you have configured Sanctum's guard to use your Employee provider. In your config/auth.php, you should have something like this:
'guards' => [
    'sanctum' => [
        'driver' => 'sanctum',
        'provider' => 'employees', // Make sure this is pointing to the correct provider
    ],
    // other guards...
],
  1. Provider Key: In the providers array, you have used 'users' as the key. You might want to change that to 'employees' to avoid confusion and clearly indicate that you are using a different provider:
'providers' => [
    'employees' => [ // Changed from 'users' to 'employees'
        'driver' => 'eloquent',
        'model' => env('AUTH_MODEL', App\Models\Employee::class),
        'table' => env('AUTH_TABLE', 'employee.Employee'),
    ],
    // other providers...
],
  1. Middleware Configuration: Ensure that your route middleware is using the correct guard. If you've changed the provider key as suggested above, you should also update the middleware to use the employees guard:
Route::group(['middleware' => ['auth:sanctum']], function() {
    Route::get('/test', [TestController::class, 'test']);
});

If you've renamed the guard to employees, then you should specify it in the middleware like this:

Route::group(['middleware' => ['auth:employees']], function() {
    Route::get('/test', [TestController::class, 'test']);
});
  1. Personal Access Token: Ensure that the personal access token you are using for authentication belongs to an Employee instance and not a User instance. When you create tokens, you should be doing so from an Employee instance:
$employee = Employee::find(1); // Example employee instance
$token = $employee->createToken('token-name')->plainTextToken;
  1. Request Headers: When making the request to the /test route, ensure that you are passing the correct authentication token in the request headers:
Authorization: Bearer your-personal-access-token
  1. Database Connection: Since you mentioned that you are using multiple schemas, ensure that your Employee model is using the correct database connection if it's different from the default. You can specify the connection in your Employee model like this:
protected $connection = 'your_custom_connection_name';

After checking and ensuring all these configurations are correct, try to authenticate again. If it still doesn't work, you might want to clear your configuration cache with php artisan config:clear and check the logs for any additional errors that could give you more insight into the issue.

FunCoding's avatar

Nevermind. I seem to be on a streak of idiotic mistakes. It works perfectly, I forgot to put in the token in the postman request. Duh.

1 like

Please or to participate in this conversation.