Ulid e Uuid do Jeito certo!

Todos nós já tivemos aquela dúvida cruel, usar Uuid, usar Ulid, ou usar id, mas Uuid, Ulid é muito lento, será que deixar id exposto é uma falha de segurança? Então qual usar? Como usar? Neste pequeno artigo vou tentar desmistificar e simplificar um pouco sua decisão!

Deixar seus ids sequenciais de persistência de dados expostos na url de seu endpoint, ou no seu endereço de página não é uma boa prática de desenvolvimento.

Neste contexto, podemos considerar de certa forma que deixar número de registros do banco de dados exposto é uma má prática de desenvolvimento, acredito que considerar como uma falha de segurança em sua aplicação seja algo muito pífio, pois se seu pensamento ou conhecimento se baseia neste único item, sinceramente melhor rever conceitos de segurança, em aplicações.

Não considero como falha de segurança, mas sim como uma má prática ou até mesmo como abertura a falhas em seu projeto, principalmente quando considerarmos aplicações distribuídas como microsserviços, onde precisamos ter ids únicos, pense em um cadastro de clientes no qual este vai ser compartilhado com toda sua aplicação, e neste caso por algum motivo, foi separado a tabela de clientes em pessoa física e pessoa jurídica, ambas vão ter ids sequênciais iguais em algum dado momento, este efeito colateral é que devemos evitar, atentando que foi um exemplo bem simples, mas existem muitos outros exemplos que faz este acontecimento aparecer, principalmente em ambientes com microsserviços.

Podemos observar um exemplo na tabela abaixo, com isso em mente, sabemos que só basear a segurança de sua aplicação somente em esconder seu id, não é suficiente, porém não vamos tratar disso neste artigo.

Verbo URI Ação
GET /customers index
GET /customers/create create
POST /customers store
GET /customers/{id} show
GET /customers/{id}/edit edit
PUT/PATCH /customers/{id} update
DELETE /customers/{id} destroy

Observe que qualquer "gênio" com acesso a sua aplicação pode facilmente adivinha seu proximo cliente, e também, caso não tenha feito o dever de casa direitinho, também o mesmo poderá apagar um cliente de seu registro.

Então o que é esse Uiid ou Ulid ?

O UUID é um número de 128 bits representado por 32 dígitos hexadecimais, exibidos em cinco grupos separados por hifens, na forma textual8-4-4-4-12 sendo um total de 36 caracteres (32 caracteres alfanuméricos e 4 hifens).

15286994-6e02-4fe9-b49c-0d1d6b14956c

O ULID são Identificadores exclusivos classificáveis lexicograficamente (alfabéticamente)

01H8B3MB33DW75R4PZA9QX4YG0

ps: não tente fazer o seu, não reinvente a roda!

Verbo URI Ação
GET /customers index
GET /customers/create create
POST /customers store
GET /customers/15286994-6e02-4fe9-b49c-0d1d6b14956c show
GET /customers/15286994-6e02-4fe9-b49c-0d1d6b14956c/edit edit
PUT/PATCH /customers/15286994-6e02-4fe9-b49c-0d1d6b14956c update
DELETE /customers/15286994-6e02-4fe9-b49c-0d1d6b14956c destroy

Observe que agora ficou bem mais difícil de "adivinhar" qual será seu próximo cliente.

No entanto, ainda não está pronto, como sabemos só por isso não será suficiente para termos exposição digamos assim mais segura de nossos recursos, e também manter uma velocidade considerável nas requisições, desta forma o meu conselho:

Coloque uuid como um atributo a mais em sua aplicação coloque-o também como index do seu banco assim vai fazer com que as buscas por ele seja mais rápida, e também adicione o id sequencial número como index, para consultas SQL mais complexas.

Fazendo tudo isso usando o Laravel 9+ com Eloquent

Na sua migration faça como exemplo:

/** * Run the migrations. */ public function up(): void { Schema::create('customers', function (Blueprint $table) { $table->id(); $table->ulid()->index(); $table->string('name'); }); }

No seu model faça:

final class Customer extends Model {~~~~ use HasFactory; use HasUlids; protected $primaryKey = 'ulid'; protected $fillable = [ 'name', ]; ...

Defina sua primary key como chave primaria, assim você usará todo o poder do Laravel sem grande esforço.

ps: No Laaravel 9+ já se pode usar uuid e ulid no Laravel 8+ somente uuid nos anteriores não tem uuid e ulid por padrão no Laravel fazendo-se necessário implementar com traits, que um assunto posterior

Espero que tenham gostado ae até a próxima.

Por: J.S.Júnior