Manage SEO and track how your site performs and appears in search engine results. 

X

Laravel 11 Api Token Generation: Build A Secure Artisan Command With Sanctum

Published on May 10, 2025 by

Laravel 11 API Token Generation: Build a Secure Artisan Command with Sanctum

🔑 Laravel 11 API Token Generation: Build a Secure Artisan Command with Sanctum

Laravel Sanctum Token Generation

🚀 The Ultimate Artisan Command for Secure API Authentication

In modern Laravel applications, API authentication is often handled using Laravel Sanctum. While Sanctum provides excellent functionality out of the box, creating a robust token generation command can streamline your development workflow and enhance security. Let's build a powerful Artisan command that handles token generation with expiration dates and user management. i will not talk about the Laravel Sanctum installation and setup, you can find that in the Laravel Sanctum documentation.


💡 Why Build a Custom Token Command?

Benefit Description
⏱️ Time-Saving Generate tokens faster than manual methods
🔒 Enhanced Security Built-in expiration handling and token rotation
🤖 Automation Ready Integrates with deployment scripts and CI/CD pipelines
📊 Consistent Process Standardized token generation across your team
🛠️ Developer Experience Beautiful CLI interface with interactive prompts

🛠️ Implementation Deep Dive

1. The Token Generation Action (app/Actions/GenerateTokenAction.php)

This action handles the core logic of generating a token for a user. It checks if the user exists, creates a new one if not, and generates a token with an optional expiration date.

<?php
 
declare(strict_types=1);
 
namespace App\Actions;
 
use Carbon\Carbon;
use App\Models\User;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\Hash;
 
final class GenerateTokenAction
{
public function execute(string $username, ?string $expires = null): array
{
$user = User::query()
->firstOrCreate(
['email' => $username],
[
'name' => $username,
'password' => Hash::make(Str::random(16)),
]
);
 
$user->tokens()->delete();
 
$expiresAt = $expires !== null && $expires !== '' && $expires !== '0' ? Carbon::parse($expires) : null;
$token = $user->createToken(
name: $username,
expiresAt: $expiresAt,
);
 
return [
'user' => $user->name,
'token' => $token->plainTextToken,
'expires_at' => $expiresAt,
'created_at' => $user->created_at,
];
}
}

Key Features:

  • 🔄 Automatic token rotation (deletes old tokens)
  • 🔐 Secure password generation for new users
  • ⏳ Flexible expiration handling
  • 📦 Clean, standardized return format

2. The Artisan Command (app/Console/Commands/GenerateToken.php)

Create a new Artisan command using the following command:

php artisan make:command GenerateToken

After that, replace the contents of the generated file with the following code:

<?php
 
declare(strict_types=1);
 
namespace App\Console\Commands;
 
use App\Actions\GenerateTokenAction;
use Illuminate\Console\Command;
use Illuminate\Contracts\Console\PromptsForMissingInput;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use function Laravel\Prompts\{clear, confirm, info, progress, text};
 
final class GenerateToken extends Command implements PromptsForMissingInput
{
protected $signature = 'generate:token
{username : User email or username}
{expires? : Expiration date (e.g. "1 day", "2025-12-31")}';
 
protected $description = 'Generate or update user token with expiration';
 
public function handle(GenerateTokenAction $action): void
{
$expires = $this->argument('expires') === 'yes'
? text('Enter expiration (e.g., "1 day", "2025-12-31")')
: $this->argument('expires');
 
$results = progress(
label: 'Generating token',
steps: 1,
callback: function () use ($action, $expires): array {
sleep(1); // Simulate a delay for the progress bar note: this is just for demonstration
 
return $action->execute(
username: $this->argument('username'),
expires: $expires,
);
},
);
 
// Extract the first (and only) result from the progress array
$result = $results[0];
$this->line('');
info('✅ API Token Generated Successfully');
$this->table(
['🆔 User', '🔑 Token', '⏳ Expires At'],
[
[
$result['user'],
$result['token'],
$result['expires_at']->toDateTimeString(),
],
]
);
}
 
protected function promptForMissingArgumentsUsing(): array
{
return [
'username' => 'Enter the username or email address',
];
}
 
protected function afterPromptingForMissingArguments(InputInterface $input, OutputInterface $output): void
{
if (confirm('Do you want to set an expiration date for the token?')) {
$input->setArgument(
'expires',
text('Enter expiration (e.g., "1 day", "2025-12-31")')
);
}
}
}

UX Enhancements:

  • 🎨 Color-coded output
  • 🔄 Progress indicators
  • ❓ Interactive prompts
  • 📝 Clear, organized information display

🏗️ Usage Examples

🔧 Basic Interactive Mode

php artisan generate:token

Prompts for:

  • Username/Email address
  • Whether to set expiration
  • Expiration timeframe if selected

⚡ Direct Command Usage

# Token without expiration
php artisan generate:token [email protected]
 
# Token with 30-day expiration
php artisan generate:token [email protected] "30 days"

🤖 CI/CD Integration

# Create deployment token (expires in 1 hour)
php artisan generate:token [email protected] "1 hour" >> deploy_token.txt

Output

 
✅ API Token Generated Successfully
 
+---------+-----------------------------------------------------+---------------------+
| 🆔 User | 🔑 Token | ⏳ Expires At |
+---------+-----------------------------------------------------+---------------------+
| bb | 50|q2uPCYho0wHnZ2AvPtBia8IB8hp9hRWpfqUD8crA20370e93 | 2025-05-15 07:49:51 |
+---------+-----------------------------------------------------+---------------------+

🚀 Advanced Extensions

you can enhance more features such as given in flow chart.

flow chart


🎯 Conclusion

This implementation provides:

  • Enterprise-grade security 🔐 in a developer-friendly package
  • Beautiful CLI UX 🎨 that teams will love using
  • Production-ready features 🏗️ out of the box
  • Extensible architecture ⚙️ for future needs

Dinesh Uprety

Senior Software Engineer • Writer @ Laranepal • PHP, Laravel, Livewire, TailwindCSS & VueJS • CEO @ Laranepal & Founder @ laracodesnap

Filed in:

Discussion

Login or register to comment or ask questions

No comments or questions yet...

SPONSORED
MetaMagnet

Metamagnet

 Manage SEO and track how your site performs and appears in search engine results.