Dev (Back & Front)ARTIGO

Autenticação com Zend Framework

Veremos aqui uma explicação detalhada dos componentes de Autenticação do
Zend Framework, demonstrando como restringir acesso a uma aplicação e
como, baseado nas credenciais de um usuário, verificar se ele está apto
ou não a acessar os recursos protegidos da aplicação.

Conceitos

Autenticação é o ato de determinar se uma entidade é aquilo que ela
diz ser, baseado em suas credenciais. Explicando de uma forma mais
clara, é o ato de verificar determinados dados de um usuário e, caso
ele realmente seja um usuário válido da aplicação, identificá-lo para
que a aplicação saiba quem ele é. No Zend Framework, essa funcionalidade é
fornecida pelo componente Zend_Auth, que além de prover uma API
para autenticação, também inclui adaptadores concretos de autenticação
para cenários comumente encontrados.

Um adaptador Zend_Auth é utilizado para fazer a autenticação em um
serviço de autenticação específico, como, por exemplo, LDAP, banco de
dados e arquivos físicos. Cada adaptador terá certas particularidades de
comportamentos e opções, porém algumas características básicas serão
encontradas em todos os adaptadores, como aceitar credenciais de
acesso, efetuar consultas no serviço de autenticação e retornar
resultados. Os adaptadores implementam a interface Zend_Auth_Adapter_Interface,
esta definindo o método authenticate(), que cuida da consulta
utilizada na autenticação, que deverá ser implementada em cada um dos
adaptadores. Para a utilização desse método, cada adaptador deverá estar
devidamente configurado com os dados necessários na autenticação, como
as opções específicas do adaptador e o usuário e senha que deverão ser
utilizados.

Uma tentativa de autenticação utilizando o método authenticate()
de um adaptador Zend_Auth irá retornar como resultado uma instância da
classe Zend_Auth_Result devidamente populada com informações
para validar o retorno da autenticação. Essa classe possui os seguintes
métodos:

  • isValid() – Retorna true se e somente se o resultado
    representa uma tentativa de autenticação bem-sucedida;
  • getCode() – Retorna uma constante da classe Zend_Auth_Result
    para determinar que tipo de falha de autenticação ou sucesso que
    ocorreu. Pode ser usado em situações onde o desenvolvedor necessita
    saber o tipo de resultado ocorrido para proceder de alguma forma
    específica;
  • getIdentity() – Retorna a identidade da tentativa de
    autenticação, pode ser o nome de usuário ou alguma outra característica
    definida como identidade;
  • getMessages() – Retorna um array de mensagens sobre
    uma tentativa de autenticação mal-sucedida.

As constantes que podem ser retornadas no método getCode() são
listadas abaixo:

Zend_Auth_Result::SUCCESS //Sucesso na  autenticação<br />Zend_Auth_Result::FAILURE //Falha na autenticação<br />Zend_Auth_Result::FAILURE_IDENTITY_NOT_FOUND  //Falha, a identidade é inválida<br />Zend_Auth_Result::FAILURE_IDENTITY_AMBIGUOUS  //Falha, a identidade é ambígua<br />Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID  //Falha, a senha é inválida<br />Zend_Auth_Result::FAILURE_UNCATEGORIZED  //Falha não categorizada

Efetuar corretamente uma autenticação que inclui suas devidas
credenciais é útil por si só, mas também é importante manter a
autenticação feita para não haver a necessidade de solicitar as
credenciais de autenticação a cada requisição. O HTTP é um protocolo stateless,
porém técnicas como cookies e sessões foram criadas para
facilitar o mantimento de um determinado estado durante diversas
requisições às aplicações. Por padrão, o componente Zend_Auth
armazena uma tentativa bem-sucedida de autenticação na sessão do PHPPHP44 conteúdosPadronizando seu código com PHP CS FixerDev (Back & Front) · mai 2019Docker de imagem. Para rodar projetos PHP em menos de 30 segundosDev (Back & Front) · jan 2026PHP 7.3: conheça as novidades desta versãoDev (Back & Front) · abr 2019Ver tudo em Dev (Back & Front) . Ele utiliza uma classe de armazenamento chamada Zend_Auth_Storage_Session
que utiliza a classe Zend_Session para manipular as sessões.
Também pode-se utilizar para armazenamento uma classe customizada, para
isso basta prover um objeto que implemente a classe Zend_Auth_Storage_Interface
para o método Zend_Auth::setStorage().

Codificando a Autenticação

Após explicar detalhadamente os conceitos que envolvem autenticação é
hora de codificar um exemplo simples que fará uso dos componentes do
Zend Framework. Esse exemplo precisará de uma tabela no banco de dadosBanco de dados134 conteúdosSQL ou NoSQL: eis a questão!!Data · mar 2020Banco de dados: como organizar e dar segurança para milhões de dados de loteriasData · mai 20215 serviços gratuitos na cloud para bancos de dados PostgresData · fev 2025Ver tudo em Data
onde serão armazenados os usuários do sistema. Essa tabela está descrita
a seguir:

CREATE TABLE `usuario`(<br />	id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,<br />	login VARCHAR(30) NOT NULL UNIQUE,<br />	senha VARCHAR(60) NOT NULL,<br />	nome_completo VARCHAR(100) NOT NULL<br />);

É inserido então um usuário de exemplo que estará apto a se
autenticar no sistema:

INSERT INTO `usuario` VALUES ('', 'admin', SHA1('admin'), 'Administrador');

É possível notar que é uma tabela extremamente simples, porém essa
estrutura já é o suficiente para utilizar no exemplo desenvolvido. Para
esse exemplo foi criado um projeto padrão do Zend Framework com o
seguinte comando:

zf create project zend_auth

Este projeto conterá um controlador de notícias, que seria um recurso
apenas disponível para usuários autenticados no sistema, e outro
controlador de autenticação, utilizado para fazer login e logout da
aplicação. Para criar esses controladores e as ações de autenticação, os
seguintes comandos são utilizados:

cd zend_auth<br />zf create controller noticias<br />zf create controller auth<br />zf create action login Auth<br />zf create action logout Auth

O próximo passo é configurar o adaptador do banco de dados MySQL, e
configurar o controlador de notícias como o controlador padrão da
aplicação. No arquivo application.ini, localizado na pasta application/configs,
basta acrescentar o seguinte conteúdo:

; Faz com que o controlador de notícias seja o controlador padrão<br />resources.frontController.defaultControllerName = "noticias"<br />; Banco de dados<br />resources.db.adapter = "PDO_MYSQL"<br />resources.db.params.host = "localhost"<br />resources.db.params.username = "root"<br />resources.db.params.password = ""<br />resources.db.params.dbname = "zend_auth"

Agora o último passo é configurar o Autoload de classes do Zend
Framework. Para isso, basta abrir o arquivo application/Bootstrap.php
e adicionar o seguinte método na classe:

protected function _initAutoload()<br />{<br />	$autoloader = new Zend_Application_Module_Autoloader(array(<br />			'basePath' => APPLICATION_PATH,<br />			'namespace' => ''<br />	));<br />	return $autoloader;<br />}

Formulário de Login

Todo sistema que precisa de autenticação fornece um formulário onde o
usuário pode informar suas credenciais para se identificar no sistema.
Para criar o formulário de login, pode-se utilizar o componente Zend_Form,
colocando os campos de login e senha. Para isso, primeiramente basta
executar o seguinte comando:

zf create form login

Com isso, um arquivo nomeado Login.php poderá ser encontrado
dentro de application/forms. Para criar o formulário, basta
colocar o seguinte conteúdo neste arquivo:

<?php<br /><br />class Form_Login extends Zend_Form<br />{<br />	public function init()<br />	{<br />		$this->setName('login');<br /><br />		$login = new Zend_Form_Element_Text('login');<br />		$login->setLabel('Login:')<br />			  ->setRequired(true)<br />			  ->addFilter('StripTags')<br />			  ->addFilter('StringTrim')<br />			  ->addValidator('NotEmpty');<br /><br />		$senha = new Zend_Form_Element_Password('senha');<br />		$senha->setLabel('Senha:')<br />			  ->setRequired(true)<br />			  ->addFilter('StripTags')<br />			  ->addFilter('StringTrim')<br />			  ->addValidator('NotEmpty');<br /><br />		$submit = new Zend_Form_Element_Submit('submit');<br />		$submit->setLabel('Logar')<br />			   ->setAttrib('id', 'submitbutton');<br /><br />		$this->addElements(array($login, $senha, $submit));<br />	}<br />}

Nesse código são criados os campos login e senha, onde
ambos possuirão filtros que farão uma limpeza nos dados fornecidos pelo
usuário, tirando espaços vazios e tags HTML, e uma validação de campos
obrigatórios. Após criar esses elementos é criado o botão de envio e,
por último, todos os elementos são adicionados ao corpo do formulário.
Estudar mais a fundo o componente Zend_Form foge do escopo deste
artigo, só este componente pode ser assunto de vários outros artigos.

Ação de Login

Após criar o formulário é hora de implementar a ação de login. O
seguinte código ficará encarregado de efetuar o login na aplicação:

public function loginAction()<br />{<br />	$this->_flashMessenger = $this->_helper->getHelper('FlashMessenger');<br />	$this->view->messages = $this->_flashMessenger->getMessages();<br />	$form = new Form_Login();<br />	$this->view->form = $form;<br />	//Verifica se existem dados de POST<br />	if ( $this->getRequest()->isPost() ) {<br />		$data = $this->getRequest()->getPost();<br />		//Formulário corretamente preenchido?<br />		if ( $form->isValid($data) ) {<br />			$login = $form->getValue('login');<br />			$senha = $form->getValue('senha');<br /><br />			$dbAdapter = Zend_Db_Table::getDefaultAdapter();<br />			//Inicia o adaptador Zend_Auth para banco de dados<br />			$authAdapter = new Zend_Auth_Adapter_DbTable($dbAdapter);<br />			$authAdapter->setTableName('usuario')<br />						->setIdentityColumn('login')<br />						->setCredentialColumn('senha')<br />						->setCredentialTreatment('SHA1(?)');<br />			//Define os dados para processar o login<br />			$authAdapter->setIdentity($login)<br />						->setCredential($senha);<br />			//Efetua o login<br />			$auth = Zend_Auth::getInstance();<br />			$result = $auth->authenticate($authAdapter);<br />			//Verifica se o login foi efetuado com sucesso<br />			if ( $result->isValid() ) {<br />				//Armazena os dados do usuário em sessão, apenas desconsiderando<br />				//a senha do usuário<br />				$info = $authAdapter->getResultRowObject(null, 'senha');<br />				$storage = $auth->getStorage();<br />				$storage->write($info);<br />				//Redireciona para o Controller protegido<br />				return $this->_helper->redirector->goToRoute( array('controller' => 'noticias'), null, true);<br />			} else {<br />				//Dados inválidos<br />				$this->_helper->FlashMessenger('Usuário ou senha inválidos!');<br />				$this->_redirect('/auth/login');<br />			}<br />		} else {<br />			//Formulário preenchido de forma incorreta<br />			$form->populate($data);<br />		}<br />	}<br />}

Inicialmente, é necessário instanciar o formulário de login e passá-lo
para a camada View, para exibi-lo ao usuário. Caso esse formulário seja
enviado para processamento o método $this->getRequest()->isPost(),
irá retornar true, e então toda a lógica para efetuar o login
será executada. Primeiramente, os dados do formulário são recuperados
através do método $this->getRequest()->getPost(), então é
feita uma verificação se os dados foram preenchidos corretamente, caso
eles não foram preenchidos, ele não entrará na lógica de login e
executará o trecho:

} else {<br />	//Formulário preenchido de forma incorreta<br />	$form->populate($data);<br />}

que, basicamente, irá preencher o formulário com os dados já enviados,
para o usuário não precisar reinformá-los, permitindo exibi-los na View.
No caso de o formulário ser preenchido corretamente, a lógica de
autenticação é executada, onde são recuperados os valores preenchidos do
formulário através do método getValue(atributo), e finalmente os
componentes do Zend Framework entram em ação, primeiramente é
recuperado o adaptador de banco de dados sendo executado pela aplicação
e, então ele é passado para a classe Zend_Auth_Adapter_DbTable,
que, após ser instanciada, é configurada para utilizar a tabela usuario
do banco de dados, utilizando como Identidade a coluna login,
e como Credencial a coluna senha, e como Tratamento de
senha o formato de criptografia SHA1.

Após configurar o adaptador os dados informados pelo usuário, são
passados para o mesmo, em seguida o componente Zend_Auth é
iniciado, e é efetuada uma tentativa de autenticação. Caso o resultado
seja válido, é armazenado um objeto com os dados do usuário em sessão,
excluindo apenas sua senha por questões de segurança, e o usuário é
redirecionado para o controlador de notícias. Caso o resultado seja
inválido, é criada uma mensagem de erro através do componente FlashMessenger,
que é instanciado no início dessa action passando as possíveis
mensagens armazenadas para a camada View, e então o usuário é
redirecionado para o formulário de login, que conterá uma mensagem
informando sobre o erro encontrado.

Agora a última etapa é codificar a View login.phtml,
localizada na pasta application/views/scripts/auth, para exibir o
formulário e as possíveis mensagens de erro. O código desse arquivo é
apresentado a seguir:

<h2>Login</h2><br /><?php echo ( sizeof( $this->messages ) > 0 ) ? $this->messages[0] : ""; ?><br /><?php echo $this->form; ?>

Esse arquivo é extremamente simples, ele terá uma verificação se
existem mensagens de erro para exibir ao usuário, caso existam ele irá
imprimi-las, e irá exibir o formulário de login. Como o componente Zend_Form,
encapsula toda a validação, não é necessário mais nenhum código. Agora,
para testar, basta apontar o browser para o projeto, no meu caso estou
utilizando a seguinte url: http://zend_auth/auth/login. A seguinte
imagem deverá ser exibida:

Agora a última etapa é configurar a ação indexAction para
redirecionar para a ação de login. Para isso, basta deixá-la da seguinte
forma:

public function indexAction()<br />{<br />	return $this->_helper->redirector('login');<br />}

Logout

Efetuar logout com os componentes do Zend Framework é uma etapa
extremamente simples. Na classe AuthController foi criada a ação logoutAction,
basta alterá-la para que ela fique da seguinte forma:

public function logoutAction()<br />{<br />	$auth = Zend_Auth::getInstance();<br />	$auth->clearIdentity();<br />	return $this->_helper->redirector('index');<br />}

Basicamente é recuperada a instância do Zend_Auth e é feita
uma limpeza dos dados do usuário logado, após isso o usuário é
redirecionado ao formulário de login, para que ele realmente saiba que
agora ele não está mais autenticado no sistema.

Controlador de notícias

O Controlador de notícias será o ponto de verificação de todo o
processo de login. Neste exemplo ele é uma área restrita, portanto é
necessário protegê-lo do acesso de usuários não-autenticados. O método init()
é acessado antes de qualquer ação de um controlador, portanto ele é o
ponto ideal para fazer a proteção do controlador. Para obter essa
proteção, basta modificar este método, no arquivo NoticiasController.php,
deixando-o com o seguinte conteúdo:

public function init()<br />{<br />	if ( !Zend_Auth::getInstance()->hasIdentity() ) {<br />		return $this->_helper->redirector->goToRoute( array('controller' => 'auth'), null, true);<br />	}<br />}

Mais um código extremamente simples, ele irá verificar se existe
alguma identidade autenticada no sistema, e, caso não exista, o usuário
será redirecionado para o formulário de login.

Agora no método indexAction() será feita uma breve codificação
para que a sua View possa informar os dados do usuário, junto com um
link para efetuar o logout da aplicação. Esse código fica da seguinte
forma:

public function indexAction()<br />{<br />	$usuario = Zend_Auth::getInstance()->getIdentity();<br />	$this->view->usuario = $usuario;<br />}

Ele recupera a identidade armazenada na instância do Zend_Auth
e passa-a para a camada de apresentação. A View dessa ação está
localizada em application/views/scripts/noticias/index.phtml, e o
seguinte conteúdo deve ser colocado nela:

<h2>Usu&aacute;rio logado: <?php echo $this->usuario->nome_completo; ?></h2><br /><p><a href="<?php echo $this->url(array('controller' => 'auth', 'action' => 'logout'), null, true); ?>">Efetuar logout</a></p>

Esse código irá mostrar o nome do usuário logado e logo abaixo um
link para efetuar logout do sistema. Após clicar neste link, pode-se
verificar se o logout foi feito com sucesso tentando acessar novamente o
controlador de notícias. O resultado será um redirecionamento para o
formulário de login, o que garante que a aplicação está devidamente
protegida.

Conclusão

Os componentes do Zend Framework são extremamente simples de se
utilizar além de fornecerem uma enorme flexibilidade de extensão.
Pode-se criar adaptadores customizados para o Zend_Auth, o que permite
estender suas funcionalidades de acordo com cada cenário, tudo isso com
um código reaproveitável e bem refinado. Neste artigo procurei abordar
os conceitos que envolvem os componentes de autenticação, com um exemplo
simples utilizando-os. De acordo com cada situação esse exemplo
precisará de uma boa refatoração para melhorar o fluxo e o
reaproveitamento de código. Para isso, recomendo a leitura do manual do
Zend Framework, encontrado logo abaixo nas referências do artigo.

Referências

é bacharel em Ciência da Computação (CESUFOZ) e especialista em Projeto e Desenvolvimento de Sistemas Baseados em Objetos para Ambiente Internet (UTFPR). Possui certificações Zend Certified Engineer PHP 5.3, ZCE PHP 5 e ZCE Zend Framework. Atualmente é Analista de Sistemas no Instituto de Tecnologia Aplicada e Inovação (ITAI), desenvolvendo interfaces web para aplicações de monitoramento de redes elétricas e disjuntores com as tecnologias Java, Spring Framework, Primefaces, HTML5, CSS3, PHP, Zend Framework, Apache Lucene e Doctrine 2.

Ver perfil