Quando seu sistema começa a crescer, ter apenas verificações básicas como “usuário pode editar este post?” pode não ser suficiente. Imagine cenários com múltiplas empresas (tenants), vários papéis (admin, editor, cliente) e permissões personalizadas. É aí que o uso avançado de Laravel Policies se torna essencial.
Neste post, você vai aprender a aplicar Policies levando em conta o papel do usuário, permissões específicas e até o tenant da empresa. Vamos criar um controle de acesso poderoso e reutilizável para qualquer tipo de sistema.
Por que usar Policies com múltiplos papéis?
Sistemas complexos exigem regras de acesso mais refinadas. Exemplo:
- Um admin global pode editar qualquer conteúdo.
- Um editor pode editar apenas seus próprios registros.
- Um cliente comum pode apenas visualizar.
Ao invés de criar centenas de ifs espalhados no código, podemos centralizar tudo em Policies com regras claras e testáveis.
Preparando o ambiente (estrutura de exemplo)
Modelos:
- User com colunas: id, role, company_id
- Post com colunas: id, user_id, company_id, title
Exemplo de roles:
const ROLES = [
'admin',
'editor',
'cliente',
];
🔨 Criando a Policy com lógica de múltiplos papéis
php artisan make:policy PostPolicy --model=Post
No método update, podemos tratar o controle assim:
public function update(User $user, Post $post)
{
if ($user->role === 'admin') {
return true; // Admin pode tudo
}
if ($user->role === 'editor' && $user->company_id === $post->company_id) {
return $user->id === $post->user_id; // Só edita os próprios
}
return false; // Cliente não pode
}
Tornando isso mais escalável: usando Permissions
Se estiver usando uma tabela de permissões (ex: permissions e role_user), você pode verificar assim:
public function delete(User $user, Post $post)
{
if ($user->hasPermission('delete_any_post')) {
return true;
}
if ($user->hasPermission('delete_own_post')) {
return $user->id === $post->user_id;
}
return false;
}
Dica: use pacotes como spatie/laravel-permission para controlar papéis e permissões de forma robusta.
Usando a Policy no Controller
public function destroy(Post $post)
{
$this->authorize('delete', $post);
$post->delete();
}
Testando suas Policies
Você pode criar testes para garantir que tudo funcione como esperado:
public function test_editor_cannot_delete_other_user_post()
{
$editor = User::factory()->create(['role' => 'editor']);
$post = Post::factory()->create(); // outro usuário
$this->actingAs($editor)
->delete(route('posts.destroy', $post))
->assertForbidden();
}
Boas práticas
- Nunca confie em verificações somente no front-end. Use sempre Policies no back-end.
- Centralize a lógica por Model (uma Policy para cada).
- Evite duplicar código — use Traits ou helpers para regras comuns.
- Use middleware como can:update,post nas rotas para segurança extra.
Está pronto para levar o controle de acesso do seu sistema a outro nível? Implemente essas técnicas com Policies e deixe sua aplicação mais segura e escalável! Curtiu o conteúdo? Compartilhe com sua equipe ou deixe um comentário com dúvidas!
Pingback: Estrutura de Pastas Laravel: Guia para Desenvolvedores -