Using Laravel Sanctum it seems tedious, that I must always explicitly delete the personal access tokens, when deleting a user:
$user = User::find(123);
$user->tokens()->delete(); // Delete Sanctum tokens
$user->delete();
I know this is not important for security, because orphaned tokens don't pass authentication. But I'm a big fan of keeping the house clean.
How can the access token deletion be automated?
My desired outcome is this code to be sufficient (implicitly deleting all sanctum tokens of this user):
User::find(123)->delete();
Inspired by @miken32's comment, here's an even better solution:
My other answer sits right inside the User model's code and cleans up tokens immediately, requiring resources at deletion time.
This answer sits outside the core application code, running at a schedule of choice, enabling efficient bulk deletion outside business hours.
php artisan make:command PruneOrphanedSanctumTokens
2. Then paste this code - it deletes all personal access tokens for which no user exists:
<?php
namespace App\Console\Commands;
use Illuminate\Console\Command;
use Illuminate\Database\Query\Builder;
use Illuminate\Support\Facades\DB;
class PruneOrphanedSanctumTokens extends Command
{
protected $signature = 'sanctum:prune-orphaned-tokens';
protected $description = 'Delete Sanctum tokens for users that no longer exist';
public function handle(): void
{
$deletedCount = DB::table('personal_access_tokens')
->whereNotExists(function (Builder $query) {
$query->select(DB::raw(1))
->from('users')
->whereColumn('users.id', 'personal_access_tokens.tokenable_id')
->where('personal_access_tokens.tokenable_type', '=', 'App\\Models\\User');
})
->delete();
$this->info("Deleted $deletedCount orphaned Sanctum token(s).");
}
}
3. Now when you run php artisan list
or more specifically php artisan sanctum list
, you should see a new command in the list:
Available commands for the "sanctum" namespace:
...
sanctum:prune-orphaned-tokens
You can execute it to have all orphaned sanctum tokens cleaned up.
php artisan sanctum:prune-orphaned-tokens
Deleted 1 orphaned Sanctum token(s).
4. Automate its execution by scheduling the artisan command to run daily in your routes/console.php
file:
use Illuminate\Support\Facades\Schedule;
Schedule::command('sanctum:prune-orphaned-tokens')->daily();
->daily()
is the frequence option for every day at midnight, when there's less traffic presumably.
If you hand out expiring tokens, you can also schedule the command to prune them here.