Home | All articles | Code

ID Obfuscation in Laravel: A Simple and Effective Solution

Php Reading time ~2 minutes
ID Obfuscation in Laravel: A Simple and Effective Solution

Why do you need ID obfuscation?

In web development, there is often a need to hide real IDs of posts (e.g. /users/1, /posts/2). Sequential numbers are easy to guess, which opens the door to parsing and unauthorized access to data.

ID obfuscation makes URLs cleaner, harder to brute force, and safer. The approach we consider:

  • does not require changing the database structure (IDs remain INT),
  • is easy to scale,
  • works very fast due to the use of built-in PHP functions.

Implementation in Laravel

Helper for encoding and decoding IDs

namespace App\Helpers;

class IdEncoder
{
    public static function encode(int $id): string
    {
        $key = (int) env('ID_OBFUSCATE_KEY');
        return base_convert($id ^ $key, 10, 36);
    }

    public static function decode(string $encoded): int
    {
        $key = (int) env('ID_OBFUSCATE_KEY');
        return (int) base_convert($encoded, 36, 10) ^ $key;
    }
}

It uses a simple XOR operation with a secret key and conversion from a 10-base system to a 36-base system (uses characters 0-9a-z), which makes the ID shorter and human-readable.

Add .env environment variable:

ID_OBFUSCATE_KEY=123456

Obfuscate IDs in API response via Resource

use App\Helpers\IdEncoder;
use Illuminate\Http\Resources\Json\JsonResource;

class UserResource extends JsonResource
{
    public function toArray($request): array
    {
        return [
            'id' => IdEncoder::encode($this->id),
            'name' => $this->name,
            'email' => $this->email,
        ];
    }
}

Using Resource is a clean way to automatically obfuscate IDs when serializing models. Everything happens centrally.

Decoding in Form Request before validation

use App\Helpers\IdEncoder;
use Illuminate\Foundation\Http\FormRequest;
class UpdateUserRequest extends FormRequest
{
    public function rules(): array
    {
        return [
            'id' => 'required|exists:users,id',
            'name' => 'required|string|max:255',
        ];
    }

    protected function prepareForValidation(): void
    {
        if ($this->has('id')) {
            $this->merge([
                'id' => IdEncoder::decode($this->id),
            ]);
        }
    }
}

Preparing data before validation allows you to use standard Laravel rules (exists, unique) without changing the logic.

Obfuscate in routes via Route Model Binding

use Illuminate\Support\Facades\Route;
use App\Helpers\IdEncoder;

class RouteServiceProvider extends ServiceProvider
{
    public function boot(): void
    {
        Route::bind('id', function ($param) {
            return IdEncoder::decode($param);
        });
    }
}

Now you can use obfuscated IDs in URLs:

Route::get('/users/{id}', [UserController::class, 'show']);

The controller will automatically get the original ID.

Benefits of the approach

  • High performance: operations are executed instantly.
  • Security: hiding the ID sequence.
  • Clean code: integration into Resources, Form Requests and Route Binding.
  • Easy to maintain: does not require changing the database structure.

Conclusion

ID obfuscation is not only about security, but also about convenience and architectural purity. The above method is easily integrated into any Laravel project and provides an excellent balance between simplicity, performance and reliability.

author
Dmitry Mikhailov
Aug 19, 2025
226

News, discussions, training

telegram
Telegram

Discussion of programming, assistance in learning

youtube
Youtube

Examples of work, training videos

Subscribe To Our Newsletter

Monthly digest of what's new and exciting from us.

© 2025 Platforms & Software. All rights reserved.

  • email
  • packagist
  • telegram
  • youtube