Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

AlexSteele's avatar

Livewire, Security, and UUIDs (oh my!)

Hello All! I am working on a test server at the moment, and I am working towards a safer app. It was suggested to me by a robot (not lary ;-) ) that gates, validation rules, and assuring certain actions (edit or delete) are gates based on permissions - is a good approach but could be stronger. two points are: my ids are guessable , and, internal ID references - if exposed, easier for malicious actors. So when editing a user, or an industry, the id is guessable and therefore a weak spot. So, a couple of options exist for me, one would be encrypting IDs, and the other is to add a policy which I mostly understand. more suggestions include Encryption at Rest, which is new to me. I did some quick research and saw that the encrypted IDs take up more space, and that led me to wonder about uuids (which are not as guessable and also take up space). so this long winded question comes round to the point: if you were setting up a new system, and you could start from scratch, would you go with UUIDs, or sequential numbers and try to encrypt them? Or another solution altogether when it comes to IDs in livewire?

0 likes
3 replies
LaryAI's avatar
Level 58

When it comes to securing your application, especially in the context of Livewire and ensuring that IDs are not easily guessable, using UUIDs (Universally Unique Identifiers) is a robust approach. UUIDs are not only harder to guess but also provide a level of uniqueness that can be beneficial in distributed systems.

Here's a step-by-step guide on how you can implement UUIDs in your Laravel application, which will work seamlessly with Livewire:

Step 1: Update Your Model

First, you need to update your model to use UUIDs instead of auto-incrementing IDs. Let's assume you have a User model.

use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Str;

class User extends Model
{
    // Disable auto-incrementing IDs
    public $incrementing = false;

    // Set the key type to string
    protected $keyType = 'string';

    // Boot method to generate UUIDs
    protected static function boot()
    {
        parent::boot();

        static::creating(function ($model) {
            if (empty($model->{$model->getKeyName()})) {
                $model->{$model->getKeyName()} = (string) Str::uuid();
            }
        });
    }
}

Step 2: Update Your Migrations

Next, you need to update your migrations to use UUIDs. Here’s how you can modify your users table migration:

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            // Use string for UUID
            $table->uuid('id')->primary();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamps();
        });
    }

    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Step 3: Update Your Routes and Controllers

Ensure that your routes and controllers are updated to handle UUIDs. For example, in your routes file:

use App\Http\Controllers\UserController;

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

And in your UserController:

use App\Models\User;

class UserController extends Controller
{
    public function show(User $user)
    {
        return view('user.show', compact('user'));
    }
}

Step 4: Update Livewire Components

If you are using Livewire components, make sure they are also updated to handle UUIDs. For example, in a Livewire component:

use Livewire\Component;
use App\Models\User;

class UserProfile extends Component
{
    public $userId;

    public function mount($userId)
    {
        $this->userId = $userId;
    }

    public function render()
    {
        $user = User::findOrFail($this->userId);
        return view('livewire.user-profile', compact('user'));
    }
}

Additional Security Measures

  1. Policies and Gates: Continue using Laravel's policies and gates to control access to resources.
  2. Validation Rules: Ensure that you validate all incoming data rigorously.
  3. Encryption at Rest: Consider using Laravel's built-in encryption features to encrypt sensitive data stored in your database.

Conclusion

Using UUIDs is a strong approach to making your IDs less guessable and more secure. It also simplifies the process compared to encrypting IDs. By following the steps above, you can implement UUIDs in your Laravel application and enhance its security.

If you have any further questions or need additional assistance, feel free to ask!

newbie360's avatar

For me

migration

    $table->id();
    $table->ulid('ulid');
    ...

Model

    protected static function booted(): void
    {
        static::creating(function (YourModel $yourModel) {
            $yourModel->ulid = str()->ulid()->toString();
        });
    }

    public function getRouteKeyName(): string
    {
        return 'ulid';
    }

id for internal use, eg. database query

1 like
AlexSteele's avatar

I am now leaning towards a dual-key approach

Please or to participate in this conversation.