Utilizando o ACL no CakePHP > cleiver.com

Utilizando o ACL no CakePHP

18.09.2008 | CakePHP
Tags: , , ,

CakePHPEstamos começando um novo projeto aqui na empresa e para ele decidimos usar o CakePHP como framework de desenvolvimento. Desde semana passada estou estudando a utilização do ACL para controle de acesso às páginas do sistema, mas como muitos devem saber, o book do site do Cake não é tão explicativo quanto deveria. :P

Quer dizer, o exemplo do conceito sendo explicado utilizando os personagens d’O Senhor dos Anéis é sensacional! Mas só serve pra isso mesmo, explicar o conceito. Por que na prática, a coisa é um pouco mais complexa.

Pra tentar entender o funcionamento, criei o blog de exemplo do próprio “Livro de Receitas” do CakePHP. Porém ele é simples demais e nem tem usuários. Então criei uma tabela para armazenar somente um login e senha de acesso. Nada muito difícil para quem já mexeu com o Cake pelo menos uma vez.

Aí vem outro problema: por padrão, o ACL vem pronto pra trabalhar com CRUD, e dificilmente teremos um sistema que só utilize os métodos do CRUD. O que fazer então? Depois de dias lendo documentação sobre o assunto, chegou até mim um texto (perdi o link, desculpem. :/) que dizia, resumidamente, que era só associar os actions como ACOs normalmente, e na hora de salvar no banco, dar acesso total nos

Então, supondo que esteja tudo pronto, vamos resolver o grande problema que encontrei nos blogs que li: Os métodos de criação dos AROs e dos ACOs, bem como seus relacionamentos, não devem ficar espalhados pela aplicação. Crie um arquivo PHP separado para executar somente quando você precisar popular o banco de dados com as informações de acesso.

Então vamos começar criando um pequeno script que cria os AROs do nosso “sistema”:

1
2
3
4
5
6
7
8
9
10
$aro = new aro();
$groups = array(
   0 => array( 'alias' => 'Admins' ),
   1 => array( 'alias' => 'Authors' ),
   2 => array( 'alias' => 'Spammers' )
   );
foreach( $groups as $group ) {
   $aro->create();
   $aro->save( $group );
}

Esse script vai gerar grupos de usuários do sistema. temos os administradores, os autores do blog e spammers, que são usuários que não terão acesso a nada.

Agora vamos criar alguns usuários:

1
2
3
4
5
6
7
8
9
10
$aro = new aro();
$users = array(
   0 => array( 'alias' => Pedro, 'parent_id' => 1 , 'model' => 'User', 'foreign_key' => 1 ),
   1 => array( 'alias' => Rafael, 'parent_id' => 2 , 'model' => 'User', 'foreign_key' => 2 ),
   2 => array( 'alias' => Adriana, 'parent_id' => 3 , 'model' => 'User', 'foreign_key' => 3 )
   );
foreach( $users as $user ) {
   $aro->create();
   $aro->save( $user );
}

Acima estou criando 3 usuários apenas, um para cada grupo. O campo parent_id aponta para o grupo que o usuário faz parte. O campo model, como o próprio nome diz, especifica um modelo. No caso, ele guarda o nome do modelo que o id armazenado em foreign_key pertence. Então no exemplo acima, o id do Pedro na tabela User é 1.

Agora vamos criar algumas ACOs:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$aco = new aco();
$group = array( 'alias' => 'Post' );
$aco->create();
$aco->save( $group );
$actions = array(
   0 => array( 'alias' => 'index' , 'parent_id' => 1 ),
   1 => array( 'alias' => 'view' , 'parent_id' => 1 ),
   2 => array( 'alias' => 'add' , 'parent_id' => 1 ),
   3 => array( 'alias' => 'delete' , 'parent_id' => 1 ),
   4 => array( 'alias' => 'edit' , 'parent_id' => 1 )
   );
foreach( $actions as $action ) {
   $aco->create();
   $aco->save( $action );
}

O processo para criação é exatamente o mesmo do utilizado no ARO. Aqui, primeiro criei um grupo com o nome do próprio controller, assim fica mais fácil organizar. Depois, criei uma ACO para cada action do controller e as relacionei com o grupo criado anteriormente.

Se você não definir nenhum tipo de permissão de acesso, por padrão, é tudo negado. Então vamos definir algumas permissões:

1
2
3
4
$this->Acl->allow( 'Admins' , 'Post' , '*' );
$this->Acl->allow( 'Authors' , 'Post' , '*' );
$this->Acl->deny( 'Authors' , 'Post/delete' , '*' );
$this->Acl->deny( 'Spammers' , 'Post' , '*' );

Na primeira linha, dei acesso total à todas as actions do controller Post para os usuários que fizerem parte do grupo Admins. Na segunda linha, dei acesso total também aos autores do blog, mas na terceira eu tirei a permissão deles de deletar algum post, ou seja, eles podem tudo, menos deletar o texto que escreveram. Assim é mais fácil do que ficar fazendo um allow para cada action do controller. Na quarta linha tirei a permissão de acesso à todas as actions do controller para quem for do grupo spammers.

Para verificar quem tem acesso ou não, dentro do seu controller, no método beforeFilter por exemplo, basta fazer o seguinte:

1
$this->Acl->check( 'Authors' , 'Post/delete' )

No nosso caso vai retornar FALSE.

Basicamente é isso. Tem outras coisas interessantes para se trabalhar junto com o ACL, como o ACLBehavior e o ACL Management Plugin. Uma boa leitura que pode ajudar um bocado é esse tutorial de utilização que um cara fez pro caso dele, tem até um sitezinho de exemplo.

Nenhum post relacionado.

5 Comentários

  1. Bruno Ribeiro

    Cara,

    Bem legal, ainda não implementei, mas me será útil, pelo que vi aqui.

  2. Luiz Lins

    Cara, vou ser sincero. Ainda não tinha intendido direito, com essa explicação simplifica ai em cima acho que vou ir longe agora valeu mesmo cara…
    fica bem, e obrigado!

  3. Jorge Aluizio

    Cara, teria como vc enviar por email o plugin acl por email?, pois não estou conseguindo baixa-lo via svn. Se puder ajudar agradeço desde já. Estou fazendo meu projeto final de graduação com o cakephp e preciso implementar controle de acesso, e o recurso de ACL é o ideal.
    Obrigado.

  4. Luiz Lins

    Jorge Aluizio, a ACL já vem inclusa no cakephp 1.2, basta inserir o seguinte comando no projeto através do prompt;

    cake schema run create DbAcl

    Atenciosamente
    Luiz Lins

  5. Alexandre de Oliveira

    Cara, parabéns, deu uma clariada. Estou quase terminando de construir um sistema com Acl, como aprendizado.

    Queria citar que eu não usei:

    cake schema run create DbAcl

    Não usei o prompt de comando para criar as tabelas do Acl. Em vez disso, basta ir na pasta app/config/sql/ no arquivo db_acl.sql. Lá tem o comando SQL para criar as tabelas.

    Não uso prompt de comando aqui, e quando colocar no servidor não quero ter que passar esse trabalho, então com o comando SQL na mão fica mais fácil.

    Abraço

Faça um comentário!

Você deve estar logado para comentar.