Imagem do artigo gerar lista de permissões

Artigo - gerar lista de permissões

01/04/2026

Ideia geral

  1. Backend (Laravel): resolve as permissões do usuário
  2. Inertia: compartilha globalmente
  3. Frontend (React): cria um helper can()

👉 Assim você chega perto do @can do Blade

🧩 1. Backend — gerar lista de permissões

No Laravel, você pode montar algo assim:

// App\Models\User.php

public function getAllPermissionsAttribute()
{
return $this->roles()
->with('permissions')
->get()
->pluck('permissions')
->flatten()
->pluck('name')
->unique()
->values();
}

🧩 2. Compartilhar globalmente (ESSENCIAL)

Aqui é o lugar correto 👇

📁 app/Http/Middleware/HandleInertiaRequests.php

public function share(Request $request)
{
return array_merge(parent::share($request), [
'auth' => [
'user' => $request->user(),
'permissions' => $request->user()
? $request->user()->all_permissions
: [],
],
]);
}

👉 Agora TODA página React recebe:

props.auth.permissions

🧩 3. Criar helper global can()

Agora vem a parte que você quer 👇

Opção A — função simples (recomendada)

// resources/js/utils/can.js

import { usePage } from '@inertiajs/react';

export function useCan() {
const { auth } = usePage().props;

function can(permission, element = null) {
const allowed = auth.permissions.includes(permission);

if (element) {
return allowed ? element : null;
}

return allowed;
}

return { can };
}

Uso:

import { useCan } from '@/utils/can';

export default function UsersPage() {
const { can } = useCan();

return (
<>
{can('cadastrar_usuarios', <button>Cadastrar</button>)}
</>
);
}

✔️ exatamente o que você queria

✔️ limpo

✔️ reutilizável

🧩 4. Alternativa MAIS React (melhor prática)

Em vez de passar elemento:

{can('cadastrar_usuarios') && <button>Cadastrar</button>}

👉 Isso é mais idiomático no React

🧩 5. Versão com componente <Can> (estilo Blade)

Se quiser algo mais bonito:

// resources/js/components/Can.jsx

import { usePage } from '@inertiajs/react';

export default function Can({ permission, children }) {
const { auth } = usePage().props;

if (!auth.permissions.includes(permission)) {
return null;
}

return children;
}

Uso:

<Can permission="cadastrar_usuarios">
<button>Cadastrar</button>
</Can>

🔥 Isso aqui fica MUITO próximo do @can

⚠️ Performance / cuidado

Se tiver muitas permissões:

  1. Pode transformar em objeto:
->pluck('name')
->flip(); // vira ['permissao' => true]

E no React:

auth.permissions['cadastrar_usuarios']

👉 lookup O(1) em vez de .includes()

🔒 Segurança (muito importante)

Isso aqui é só UI 👇

👉 SEMPRE valide no backend:

$this->authorize('cadastrar_usuarios');

ou via policy/gate.

✅ Resumo direto

  1. 📍 Lugar correto: HandleInertiaRequests
  2. 🧠 Backend resolve permissões
  3. 🌐 Front recebe via auth.permissions
  4. ⚙️ Criar useCan() ou <Can>
  5. 🚫 Não precisa Context API

Se quiser, posso te mostrar como integrar isso com Policies do Laravel (em vez de string tipo 'cadastrar_usuarios') — fica ainda mais robusto.


Ver todos os posts