pijler / personal-tokens
This package provides support for generating and validating personal tokens.
Installs: 19
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/pijler/personal-tokens
Requires
- php: ^8.2
- laravel/framework: ^11.0|^12.0
Requires (Dev)
- laravel/pint: ^1.25
- orchestra/testbench: *
- pestphp/pest: ^4.1
- pestphp/pest-plugin-laravel: ^4.0
README
This package provides support for generating and validating personal tokens in Laravel. Personal tokens are useful for temporary authentication, one-time access links, email confirmations, password resets, and other use cases that require secure and temporary access.
🧩 Features
- ✅ Secure token generation: Encrypted tokens with secure hashing
- ✅ Automatic expiration: Control over token lifetime
- ✅ One-time use: Tokens can be marked as used
- ✅ Token types: Support for different token types
- ✅ Custom payload: Storage of additional data
- ✅ Integrated middleware: Easy route protection
- ✅ Model trait: Simple Eloquent integration
- ✅ Flexible configuration: Complete behavior customization
📦 Installation
You can install the package via Composer:
composer require pijler/personal-tokens
🗄️ Publishing Migrations
Publish the package migrations:
php artisan vendor:publish --tag=personal-tokens-migrations
Run the migrations:
php artisan migrate
⚙️ Configuration
Basic Configuration
The package works out-of-the-box, but you can customize the behavior:
use PersonalTokens\TokenCreator; class AppServiceProvider extends ServiceProvider { /** * Bootstrap services. */ public function boot(): void { // Set default expiration time (in minutes) TokenCreator::expiresAt(60); // Use custom model TokenCreator::usePersonalTokenModel(CustomPersonalToken::class); // Customize token generation TokenCreator::plainTextTokenUsing(fn () => 'prefix-' . Str::random(32)); } }
🧠 Usage
1. Using the HasTokens Trait
Add the HasTokens trait to your model:
use PersonalTokens\Traits\HasTokens; class User extends Model { use HasTokens; }
2. Creating Tokens
use Illuminate\Support\Carbon; $user = User::find(1); // Basic token $token = $user->createToken('email-verification'); // Token with custom payload $token = $user->createToken( type: 'password-reset', payload: [ 'ip' => request()->ip(), 'email' => $user->email, ], ); // Token with custom expiration $token = $user->createToken( type: 'temporary-access', expiresAt: Carbon::now()->addDays(7), ); // Token with custom value $token = $user->createToken( type: 'custom-token', plainTextToken: 'my-custom-token', );
3. Validating Tokens
use PersonalTokens\TokenCreator; // Find token $personalToken = TokenCreator::findToken($tokenString); if ($personalToken && !$personalToken->isUsed() && !$personalToken->isExpired()) { // Valid token $owner = $personalToken->owner; $payload = $personalToken->payload; // Mark as used (optional) $personalToken->markAsUsed(); }
4. Using the Middleware
The package includes middleware to automatically protect routes:
// routes/web.php use Illuminate\Support\Facades\Route; // Route protected with any token Route::post('/protected', function () { return response()->json(['message' => 'Access granted']); })->middleware('personal-token'); // Route protected with specific token type Route::post('/email-verify', function () { return response()->json(['message' => 'Email verified']); })->middleware('personal-token:email-verification');
The middleware expects the token in the token parameter of the request:
// Example usage with JavaScript fetch("/protected", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ token: "your-token-here", }), });
5. Working with the PersonalToken Model
use PersonalTokens\Models\PersonalToken; // Create token directly $token = PersonalToken::createToken( model: $user, type: 'email-verification', plainTextToken: 'custom-token', expiresAt: Carbon::now()->addHour(), payload: ['action' => 'verify-email'], ); // Check token status $personalToken = PersonalToken::find(1); if ($personalToken->isUsed()) { // Token already used } if ($personalToken->isExpired()) { // Token expired } // Check if belongs to owner if ($personalToken->belongsToOwner($user)) { // Token belongs to user }
🧩 API Reference
TokenCreator
// Configuration TokenCreator::expiresAt(int $minutes): void TokenCreator::usePersonalTokenModel(string $model): void TokenCreator::plainTextTokenUsing(Closure $callback): void // Methods TokenCreator::findToken(string $token): ?PersonalToken TokenCreator::createPlainTextToken(): string TokenCreator::createToken( mixed $type, ?Model $model = null, ?array $payload = null, ?Carbon $expiresAt = null, ?string $plainTextToken = null, ): string
PersonalToken Model
// Relationships $token->owner(): MorphTo // Verification methods $token->isUsed(): bool $token->isExpired(): bool $token->belongsToOwner(Model $owner): bool // Actions $token->markAsUsed(): int // Static methods PersonalToken::createToken(...): string PersonalToken::findToken(string $token): ?self
HasTokens Trait
// Methods available on model $model->tokens(): MorphMany $model->currentToken(): ?PersonalToken $model->withToken(?PersonalToken $token): self $model->createToken( mixed $type, ?array $payload = null, ?Carbon $expiresAt = null, ?string $plainTextToken = null, ): string
📝 License
Open-source under the MIT license.