Zamiast stosować przewidywalne, inkrementowane identyfikatory w tabelach bazy danych zaleca się często, ze względów bezpieczeństwa, używanie tzw. UUID, czyli unikalnych identyfikatorów tekstowych. Taki klucz w tabeli maksymalnie niweluje skuteczność ataków polegających na kolejnym odpytywaniu URL, zwiększając jedynie parametr ID o jeden. Na przykładzie PHP i Laravela zademonstruję sposób na użycie UUID w projekcie.
Laravel i migracje tabel z kluczem UUID
Modyfikacja migracji
Standardowo tabele w migracjach posiadają klucz podstawowy zdefiniowany metodami id() lub bigIncrement().
1 2 3 4 | Schema::create('new_table', function (Blueprint $table) { $table->id(); // }); |
Jeśli chcemy zmienić klucz na UUID musimy zmodyfikować klasę migracji w taki oto sposób:
1 2 3 4 | Schema::create('new_table', function (Blueprint $table) { $table->uuid('id')->primary(); // }); |
Po uruchomieniu migracji kolumna ID w tabeli nie będzie miała już typu INT / BIGINT i właściwości auto-increment.
Modyfikacja Modeli
To jeszcze nie wszystko. Jeśli korzystamy z Modeli Eloquenta musimy wprowadzić w nich kilka zmian. Najprostszym u uniwersalnym sposobem będzie utworzenie nowego Traita, którego będziemy mogli dołączyć do każdego modelu, który będzie miał UUID jako primary key.
Trait UUID
W katalogu app/Traits utwórzmy nowy plik o nazwie Uuid.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php namespace App\Traits; use Illuminate\Support\Str; trait Uuids { protected static function boot() { parent::boot(); static::creating(function ($model) { if (empty($model->{$model->getKeyName()})) { $model->{$model->getKeyName()} = Str::uuid()->toString(); } }); } public function getIncrementing(): bool { return false; } public function getKeyType(): string { return 'string'; } } |
Ustawiamy typ klucza na ciąg znaków i wyłączamy domyślną jego inkrementację.
Dołączanie Traita w Modelu Eloquenta
Od tej pory w każdym modelu, który ma implementować UUID primary key należy dodać:
1 2 3 4 5 6 7 8 9 10 11 12 13 | <?php namespace App\Models; use App\Traits\Uuid; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; class Article extends Model { use HasFactory; use Uuid; } |
Po wywołaniu metody create() na takim modelu klucz podstawowy będzie wyglądał w ten oto sposób.
UUID został zaimplementowany z powodzeniem.
A czy Ty używasz UUID w swoim projekcie? Widzisz jakieś wady, a może same zalety?
Tagi: eloquent • guid • Laravel • model • uuid