I have a solution now.. I ended up extending Laravel\Sanctum\Guard and registering a new Illuminate\Auth\RequestGuard with the custom Sanctum Guard.
Here is the result:
app/Services/Auth/CustomSanctumGuard.php
<?php
namespace App\Services\Auth;
use Arr;
use Illuminate\Http\Request;
use Laravel\Sanctum\Events\TokenAuthenticated;
use Laravel\Sanctum\Guard;
use Laravel\Sanctum\Sanctum;
use Laravel\Sanctum\TransientToken;
class CustomSanctumGuard extends Guard
{
/**
* Retrieve the authenticated user for the incoming request.
*
* @param \Illuminate\Http\Request $request
* @return mixed
*/
public function __invoke(Request $request)
{
if ($token = $request->bearerToken() ?: $request->token) {
$model = Sanctum::$personalAccessTokenModel;
$accessToken = $model::findToken($token);
if (! $this->isValidAccessToken($accessToken) ||
! $this->supportsTokens($accessToken->tokenable)) {
return;
}
$tokenable = $accessToken->tokenable->withAccessToken(
$accessToken
);
event(new TokenAuthenticated($accessToken));
if (method_exists($accessToken->getConnection(), 'hasModifiedRecords') &&
method_exists($accessToken->getConnection(), 'setRecordModificationState')) {
tap($accessToken->getConnection()->hasModifiedRecords(), function ($hasModifiedRecords) use ($accessToken) {
$accessToken->forceFill(['last_used_at' => now()])->save();
$accessToken->getConnection()->setRecordModificationState($hasModifiedRecords);
});
} else {
$accessToken->forceFill(['last_used_at' => now()])->save();
}
return $tokenable;
}
}
}
app/Providers/AuthServiceProvider.php
<?php
namespace App\Providers;
use Auth;
use Illuminate\Auth\RequestGuard;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Gate;
use App\Services\Auth\CustomSanctumGuard;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
// 'App\Models\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
Auth::resolved(function ($auth) {
$auth->extend('custom', function ($app, $name, array $config) use ($auth) {
return new RequestGuard(
new CustomSanctumGuard($auth, config('sanctum.expiration'), $config['provider']),
request(),
$auth->createUserProvider($config['provider'] ?? null)
);
});
});
}
}
config/auth.php
<?php
return [
// ...
'guards' => [
'custom' => [
'driver' => 'custom',
'provider' => 'users',
],
// ...
],
// ...
];
config/sanctum.php
<?php
return [
// ...
'guard' => ['custom'],
// ...
];