Laravel ID Obfuscator

Sometimes the data that flows from the backend of your application to the frontend can reveal more than you want to.

Image an ecommerce scenario where every time an order is completed, a record is added to the orders table. Now imagine that you want your customers to be able to view their own orders within their own frontend account area. If you use standard incrementing IDs to identify these orders, you could easily reveal to that user the amount of orders your site gets in a time period.

What are your options?

The first option is to use UUIDs as your primary key on a table. This is probably the most robust method but it comes with a few downsides:

  • You can’t order records by insert order
  • Your database size is bigger
  • UUIDs can be pretty long

The second option is to use a standard incrementing primary key internally, but obfuscate it whenever its sent to the frontend.

Challenges of obfuscation

Of course, models pass from backend to frontend and vice-versa in a myriad different ways and having to manually apply obfuscation and de-obfuscation every time would be immensely tedious and limit your use of the Laravel framework in some ways (e.g. route model binding).

Additionally, you need a robust way to encode and decode your IDs to ensure that they always resolve to the same underlying key. You also don’t want this process to be easily implementable by an unconnected party (thus making standard encoding with base64, MD5 et al. off-limits).

The solution

This Laravel package tackles most of those challenges. Once the trait Obfuscatable is applied to your model, the following actions are automatically taken:

  • Obfuscated keys are resolved when used in route-model-binding.
  • Model find functions work with either the original key, or the obfuscated one
  • An attribute of obfuscatedId is automatically appended to your model instance to allow you to reference it internally
  • The ID is obfuscated when the model is sent to the frontend via the model’s toArray function
  • Encoding and decoding is seeded using a custom key in your config
  • You can pad the ID character length to whatever you like
  • You can even define your own alphabet to use for the obfuscated IDs
  • Applies a filter to IDs to prevent them accidentally creating offensive strings

Usage

After installing the package, simply add the supplied trait to any models you want to have the ID obfuscated on:

1use EvoMark\LaravelIdObfuscator\Traits\Obfuscatable;
2
3class User extends Authenticatable
4{
5 use Obfuscatable;
6}

Obfuscatable models will also feature automatic decoding when using the model’s find-style functions: e.g. find, findOrFail, findMany, findOrNew, findOr

// SomeController
/**
* @param string $id The obfuscated order ID
*/
public function index($id)
{
$order = Order::find($id);
}

Validation

Laravel ID Obfuscator comes with a built-in rule extension for validating incoming obfuscated ids, simply:

public function store($request)
{
$validated = $request->validate([
'id' => ['required','id_exists:users']
]);
}

Facade

You can access the encoding and decoding features anytime via the provided facade.

use EvoMark\LaravelIdObfuscator\Facades\Obfuscate;
$encoded = Obfuscate::encode(5);
$decoded = Obfuscate::decode($encoded);

Config

You can publish the package config by running the following Artisan command:

php artisan v:p --provider="EvoMark\LaravelIdObfuscator\Provider"
SettingTypeDefaultDescription
seedstringlaravel-id-obfuscatorA seed string for the encoder
lengthint8The amount of chars to pad the output to
alphabetstring[a-zA-Z0-9] (as string)The alphabet to use when encoding IDs

FAQs

Why not use UUIDs?

UUIDs can be bad for database performance, whereas this obfuscation only runs when data bridges between the backend and the frontend of your application.

Limitations

  • Laravel ID Obfuscator can only be used on incrementing primary keys
  • Since this package overrides the newEloquentBuilder method on obfuscated models, it is incompatible with any other packages that also do the same. Some examples might include:
    • https://github.com/mikebronner/laravel-model-caching
    • https://github.com/grimzy/laravel-mysql-spatial
    • https://github.com/fico7489/laravel-pivot
    • https://github.com/spatie/laravel-query-builder
    • https://github.com/dwightwatson/rememberable
    • https://github.com/chelout/laravel-relationship-events
    • https://github.com/lazychaser/laravel-nestedset
  • Presently, if an Obfuscatable model appears as part of another model as a foreign key, it will not be obfuscated

Part of evoMark's contribution to Free and Open Source Software (FOSS)

To read more about evoMark and our open-source software, head to our Open-Source Software page

composer require evo-mark/laravel-id-obfuscator
Get in Touch

Get in touch with us today 01202 790300

monday 09:00 - 17:00
tuesday 09:00 - 17:00
wednesday 09:00 - 17:00
thursday 09:00 - 17:00
friday 09:00 - 16:00
saturday Closed
sunday Closed