terça-feira, 21 de abril de 2009

Implementado Zend Auth no Zend Framework

Vamos partir do princípio que você tem uma aplicação já pronta em Zend Framework, como a que você monta com o quick start no site do Zend (http://framework.zend.com/docs/quickstart). E depois de tudo isso você precisa criar uma área restrita na sua aplicação. Isso é até que simples usando Zend Auth, só é um pouco trabalhoso, você vai precisar:

1. Um formulario (Zend_Form), com os campos login, senha e submit, veja mais sobre Zend Form clicando aqui. Você pode ter um decorator também para mostrar a mensagem de erro:
$this->setDecorators(array(
            'FormElements',
            array('HtmlTag', array('tag' => 'dl', 'class' => 'zend_form')),
            array('Description', array('placement' => 'prepend')), 'Form'   ));

2. Uma tabela de login no banco de dados com no mínimo os campos login e senha. 

3.  Um Zend_Db_Table_Abstract, os meus ficam em "application/models/DbTable/nomeDaTabela.php". Você pode criar essa classe sem nada de especial, ou já especificar o update e o delete:
 class Model_DbTable_Login extends Zend_Db_Table_Abstract
{
    protected $_name    = 'login';
public function insert(array $data)
    {
       throw new Exception('Nao e permitido inseir login.'); 
    }
public function update(array $data, $where)
    {
        throw new Exception('Por enquanto nao ha update.');
    }
}

4.Depois é preciso criar o model "Model_Login" "application/models/nomeDaTabela.php" ele usa o Zend_Db_Table_Abstract para realizar as operações no banco de dados e é nesse aqui que a autenticação será gravada utilizando dois métodos:

Primeiro é criado uma instância de Zend_Auth_Adapter_DbTable, ele receberá os dados que serão gravados na sessão:
 public function getAuth(){
     return  new Zend_Auth_Adapter_DbTable(    Zend_Db_Table_Abstract::getDefaultAdapter(),   
      'login',    'login',    'password');
    }

Depois é só fazer o Fetch Entry para validar o login:
    public function fetchEntry($login, $password)
    {
        $authAdapter=$this->getAuth(); //pega a instancia criada acima
     $authAdapter->setIdentity($login)->setCredential($password);  //envia login e passowrd para a validacao    
     $result = $authAdapter->authenticate(); //tenta a autenticação
    
     if($result->isValid()){ //se autenticou
      
     $authAdapter->getResultRowObject(); //pega o resultado da autenticação 
     $auth = Zend_Auth::getInstance(); //pega a instância do Zend Auth      
     $storage = $auth->getStorage();   //pega o que foi armaznado da instância
 //abaixo é armazenado login e a senha fica null, senão ela vai ficar guardada na sessão
     $storage->write($authAdapter->getResultRowObject(array(        $login,        'login',    )));    
      $storage->write($authAdapter->getResultRowObject(null,        'password'    ));
      
     return true;
      
     } else { //se nao autenticou 
     return false;  
     }
}
   O interessante aqui é que toda a parte do Select... passoword=tal e fetch row e inicia a sessão, guarda os dados, etc, etc já foi feita pelo Zend Auth. Essa subclasse Zend_Auth_Adapter_DbTable é específica para logar quando o login e senha estão em um banco de dados, caso você precise logar em um LDAP ou em outro lugar é preciso usar outros adaptadores. 

5. Agora você precisa um controller para utilizar toda a arquitetura acima:
 class LoginController extends Zend_Controller_Action 
{
  public function indexAction()
    {   
     if(Zend_Auth::getInstance()->hasIdentity()){ //verifica se o login já foi efetuado
    
     $this->_helper->redirector('guestbook'); //direciona para a página restrita
        }      
     $request = $this->getRequest(); // pega a requisição, será criada no passo 6 
        $form    = $this->_getLoginForm(); //inicia o formulario criado no passo 1
       if ($this->getRequest()->isPost()) { //se o formulario foi postado
            
           
            if ($form->isValid($request->getPost())) { //se o formulario é valido
                
                
                $model = $this->_getModel(); //pego o model criado no passo 4                              
                $values=$form->getValues(); //pega os valores do form 
                
                if($model->fetchEntry($values['login'], $values['password'])==true){ //usa o fetchEntry criado no passo 4
                
                 return $this->_helper->redirector('guestbook'); //se logar direciona para a pagina restrita
                
                } else {
                
                 $form->setDescription('Login e/ou Senha incorretos. Tente Novamente. '); //usa o decorator criado no passo 1 para dizer o que o Login está incorreto

             $this->view->form = $form; //pega o form 
            
             return $this->render('index');  //renderiza para mostrar a mensagem 
                }
                
               
                
            }
        }
        $this->view->form = $form; //se não tem post é mostrado o formulario de login 
    }
}

6. Por fim é preciso criar o view que mostrará o formulario de login "application\views\scripts\login\index.phtml" com o conteúdo: 
form ?>

No exemplo acima a página restrita é chamada com 'guestbook' porque existe um guestbookAction com o conteúdo dele no loginController. Por isso antes de fazer de fazer a autenticação é preciso entender como funciona os Controller e como se manipula informações do banco de dados no Zend Framework. 

Espero que as informações ajudem ;-)









Nenhum comentário: