I have low experience with token authentication and sanctum.
General Context: I’m currently migrating a framework of mine to Laravel and still in the early stages. I know that Laravel has its own database construction mechanism that is recommended to use the migrations and the wired up Models, however, for my purpose, I’d like to use my own database (without migrations) that I use in other systems that I’ve built in the past. The idea for this system is to have a shared database, but operable through different tech stacks.
Basic Configuration:
- Laravel 8.37
- Sanctum 2.14
- PHP 8
I had opened a previous question and made some progress with it: Laravel Authentication API Sanctum – With Custom Database
The Goal: Basically, I´d like to create a token from one controller using my custom model.
Controller that is creating the token:
$oudRecord = new UsersDetails($oudRecordParameters);
$oudRecordData = $oudRecord->cphBodyBuild();
$oudRecordToken = $oudRecord->createToken('testing_token')->plainTextToken;
In my custom model, I’ve manage to override the createToken() already. However, from my previous interaction in the first question I posted, I know that I´ll need to override the tokens() method too. That’s where I’m stuck now.
The custom model:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Laravel\Sanctum\HasApiTokens;
use Laravel\Sanctum\Sanctum;
class UsersDetails extends Authenticatable
{
use HasFactory, HasApiTokens;
// Properties.
// ----------------------
private float $idTbUsers = 0;
private array|null $arrSearchParameters = null;
private int $terminal = 0; // terminal: 0 - admin | 1 - frontend
private string $labelPrefix = 'backend';
private array|null $arrSpecialParameters = null;
private array|null $resultsUsersDetails = null;
private array|null $oudRecordParameters = null;
protected mixed $objUsersDetails = null;
protected array|null $arrUsersListing = null;
// ----------------------
/**
* Constructor.
* @param ?array $_oudRecordParameters
*/
public function __construct(?array $_oudRecordParameters = null)
{
if ($_oudRecordParameters !== null) {
$this->oudRecordParameters = $_oudRecordParameters;
}
if ($this->terminal === 1) {
$this->labelPrefix = 'frontend';
}
}
/**
* Build content placeholder body.
* @return array
*/
public function cphBodyBuild(): array
{
// Variables.
// ----------------------
$arrReturn = ['returnStatus' => false];
// ----------------------
// Logic.
try {
// Build object - details.
if ($this->oudRecordParameters !== null) {
$oudRecord = new \SyncSystemNS\ObjectUsersDetails($this->oudRecordParameters);
$arrReturn['oudRecord'] = $oudRecord->recordDetailsGet(0, 1);
if ($arrReturn['oudRecord']['returnStatus'] === true) {
$arrReturn['returnStatus'] = true;
}
}
} catch (Error $cphBodyBuildError) {
if ($GLOBALS['configDebug'] === true) {
throw new Error('cphBodyBuildError: ' . $cphBodyBuildError->message());
}
} finally {
//
}
return $arrReturn;
}
public function tokens()
{
return $this->morphMany(Sanctum::$personalAccessTokenModel, 'tokenable', "tokenable_type", "tokenable_id");
}
/**
* Override createToken method.
*/
public function createToken(string $name, array $abilities = ['*'])
{
$token = $this->tokens()->create([
'name' => $name,
'token' => hash('sha256', $plainTextToken = Str::random(80)),
'abilities' => $abilities,
]);
return new NewAccessToken($token, $token->id.'|'.$plainTextToken);
}
}
I´m getting the following error now:
local.ERROR: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'tokenable_id' cannot be null (SQL: insert into `personal_access_tokens` (`name`, `token`, `abilities`, `tokenable_id`, `tokenable_type`, `updated_at`, `created_at`) values (testing_token, 51feaf295d0fc9170bb25cf09160c325a9d685477ef4d2aa6226ed9e4085ac66, ["*"], ?, App\Models\UsersDetails, 2023-03-11 13:16:59, 2023-03-11 13:16:59)) {"exception":"[object] (Illuminate\\Database\\QueryException(code: 23000): SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'tokenable_id' cannot be null (SQL: insert into `personal_access_tokens` (`name`, `token`, `abilities`, `tokenable_id`, `tokenable_type`, `updated_at`, `created_at`) values (testing_token, 51feaf295d0fc9170bb25cf09160c325a9d685477ef4d2aa6226ed9e4085ac66, [\"*\"], ?, App\\Models\\UsersDetails, 2023-03-11 13:16:59, 2023-03-11 13:16:59)) at …
I sense that I must, somehow, provide values for some of the fields that Laravel Sanctume tried to record in the database, but I have no idea how to do that? Would it be by overriding properties? Or using another structure in token() override method?
Thanks!