I have a Laravel REST API that exclusively serves authenticated users. Authentication is done via Laravel Sanctum.
Now for local development on the API, I seed the database with three users.
User::factory()->count(2)->hasLocations(100)->create(); // two users with related data
User::factory()->create(); // another user
However, I cannot use those users to work on the API and test stuff out, because they don't have access tokens!
How to automatically create Sanctum tokens for my users while seeding and log them to a file?
This can easily be achieved as such:
class DatabaseSeeder extends Seeder
{
public function run(): void
{
File::put(base_path('sanctum_tokens.txt'), '');
$users = collect([
User::factory()->count(2)->hasLocations(100)->create(),
User::factory()->create()
])->flatten();
$users->each(function (User $user) {
$token = $user->createToken('basic-token')->plainTextToken;
$line = "{$user->id} | {$user->name} | {$token}" . PHP_EOL;
File::append(base_path('sanctum_tokens.txt'), $line);
});
}
}
* given your User model has the fields
id
andname
, if that's not the case, change{$user->id}`
and`{$user->name}
to anything that identifies a user for you.
Create an empty sanctum_tokens.txt
file at the root of your project.
Gather your created User models to a Laravel collection and flatten it because the line with ->count(2)
creates a nested collection which we don't want. We hereby get a collection of plain User models.
Iterate over the collection of users now, create a token for every one and append a new line to the sanctum_tokens.txt
file with the desired information.
Many small write operations are always far more expensive for the operating system than a single combined write operation.
Thus, if you care about performance, consider this solution, which writes the file at once.
class DatabaseSeeder extends Seeder
{
public function run(): void
{
$users = collect([
User::factory()->count(2)->hasLocations(100)->create();
User::factory()->create();
])->flatten();
$lines = $users->map(function (User $user) {
$token = $user->createToken('basic-token');
return "{$user->id} | {$user->name} | {$token->plainTextToken}";
});
File::put(base_path('sanctum_tokens.txt'), $lines->implode("\n"));
}
}