dialloibrahima / eloquent-hashids
Hashids obfuscation for Laravel models
Installs: 8
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 0
Forks: 0
Open Issues: 0
pkg:composer/dialloibrahima/eloquent-hashids
Requires
- php: ^8.2
- illuminate/contracts: ^10.0||^11.0||^12.0
- illuminate/database: ^10.0||^11.0||^12.0
- illuminate/support: ^10.0||^11.0||^12.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.0
- laravel/pint: ^1.14
- nunomaduro/collision: ^8.8
- orchestra/testbench: ^10.0.0||^9.0.0
- pestphp/pest: ^4.0
- pestphp/pest-plugin-arch: ^4.0
- pestphp/pest-plugin-laravel: ^4.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
- spatie/laravel-ray: ^1.35
README
A Laravel package that automatically obfuscates Eloquent model IDs in URLs by converting them to reversible hash strings. This improves security and aesthetics by hiding sequential database IDs.
Features
- ✅ Zero dependencies - Uses a custom Base62 encoder
- ✅ Automatic route model binding - Works seamlessly with Laravel routes
- ✅ Reversible hashes - Decode hashids back to original IDs
- ✅ Per-model configuration - Customize prefix, suffix, length per model
- ✅ Laravel 10, 11, 12 support
Installation
composer require dialloibrahima/eloquent-hashids
Publish the config file:
php artisan vendor:publish --tag="eloquent-hashids-config"
Usage
Basic Usage
Add the Hashidable trait to your model:
use DialloIbrahima\EloquentHashids\Hashidable; class User extends Model { use Hashidable; }
Now you can use hashids in your URLs:
// Get the hashid $user->hashid; // "aBcD3FgH1jKlM4nP" // Find by hashid User::findByHashid('aBcD3FgH1jKlM4nP'); User::findByHashidOrFail('aBcD3FgH1jKlM4nP'); // Route model binding works automatically Route::get('/users/{user}', function (User $user) { return $user; }); // URL: /users/aBcD3FgH1jKlM4nP
Per-Model Configuration
Implement HashidableConfigInterface to customize hashids per model:
use DialloIbrahima\EloquentHashids\Contracts\HashidableConfigInterface; use DialloIbrahima\EloquentHashids\Hashidable; class Invoice extends Model implements HashidableConfigInterface { use Hashidable; public function hashidableConfig(): array { return [ 'prefix' => 'inv', 'suffix' => 'v1', 'length' => 12, 'separator' => '_', ]; } } // Result: inv_aBcD3FgH_v1
API Resources
Expose hashids in your API responses:
class UserResource extends JsonResource { public function toArray($request) { return [ 'id' => $this->hashid, 'name' => $this->name, 'email' => $this->email, ]; } }
Configuration
// config/eloquent-hashids.php return [ 'length' => 16, // Minimum hashid length 'alphabet' => 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', 'salt' => env('HASHID_SALT', env('APP_KEY', '')), 'prefix' => '', // Optional prefix 'suffix' => '', // Optional suffix 'separator' => '-', // Separator for prefix/suffix ];
Custom Route Binding
If your model already has a custom resolveRouteBinding(), use the helper method:
class User extends Model { use Hashidable; public function resolveRouteBinding($value, $field = null): ?Model { // Your custom logic here... // Then resolve the hashid return $this->resolveHashidRouteBinding($value); } }
⚠️ Warning: Changing the
saltwill invalidate all existing hashids!
Testing
composer test
Security
Hashids provide obfuscation, not encryption. They:
- ✅ Hide sequential IDs
- ✅ Prevent URL enumeration
- ❌ Are NOT cryptographically secure
- ❌ Do NOT replace authentication/authorization
Always use proper authorization in your controllers:
public function show(User $user) { $this->authorize('view', $user); return $user; }
Credits
License
The MIT License (MIT). Please see License File for more information.