Back-End

15 jan, 2010

Utilizando o AuthComponent no CakePHP

Publicidade

Olá, galera, hoje veremos como utilizar uma classe muito
procurada no CakePHP: o AuthComponent.

Algo trabalhoso no
desenvolvimento de uma app é fazer o sistema de login, você precisa
verificar se o usuário preencheu todos os campos, criptografar
senhas, valida, etc. Mas agora isso
acabou. Com o AuthComponent tudo fica mais fácil, o Cake faz
praticamente tudo sozinho e mais! Veremos como fazer um simples,
porém eficaz sistema de login utilizando este componente.

Vamos
começar modelando nossa tabela da base de dados. O CakePHP espera
que tenhamos uma tabela chamada “users” com pelo menos três campos: id,
username
e password.
Um detalhe: a senha estará no formato de hash (sha256),
por este motivo deixaremos o campo password com o tipo 64
CHAR.
Vamos criar a tabela e já inserir um usuário nela.

CREATE TABLE `users` (
`id` int(11) NOT NULL auto_increment,
`username` varchar(255) default NULL,
`password` char(64) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

INSERT INTO `users` VALUES (1,'admin','2d02f2e3ed7978d0d89e13f1173bb5cdd580242ae01e3a764c40cdd6b53faf86'); // Usuario: admin Senha: admin

Vamos
criar agora o model,
controller
e um view:


UsersController:

<?php
class UsersController extends AppController {
var $name = 'Users';

function area_restrita(){

}
}
?>


User
Model:

<?php
class User extends AppModel {
var $name = 'User';
}
?>

area_restrita.ctp:

<p>Você só verá isso se estiver autenticado.</p><br />
<?= $html->link('CLIQUE AQUI PARA SAIR' , array('controller' => 'users' , 'action' => 'logout')); ?>

Até
aqui ainda não fizemos nada referente à autenticação (exceto a
tabela). Também criamos um link no view
“area_restrita”,
explicarei sobre ele depois. Vamos agora adicionar o AuthComponent
em nossa App e dizer qual algoritmos iremos utilizar. Iremos
adicionar em app_controller, para assim, todos os controllers filhos
também exigirem que o usuário se logue antes de visualizar qualquer
coisa.

<?php
class AppController extends Controller {
var $name = 'App';
var $components = array('Auth');

function beforeFilter(){
Security::setHash('sha256'); // Setamos o algoritmo que iremos utilizar, o padrão é sha1
}
}
?>

Aqui
incluímos o componente de autenticação na propriedade $components,
assim fazendo que todas as actions de todos os controllers exijam
autenticação. E logo depois definimos um método chamado
“beforeFilter”,
este método será chamado antes de qualquer view ou action ser
processada e renderizada. E dentro deste método setamos qual
algoritmos iremos utilizar, aqui estamos utilizando “sha256”
que gerará um hash com tamanho de 64 caracteres. Os valores aceitos
são: md5,
sha1
e sha256.
Lembre que qualquer configuração deverá ser feita em
“beforeFilter”.

Agora,
toda vez que formos entrar numa action, o componente nos
redirecionará para a action “login” do controller “users”
– este é o padrão, é possível alterar, falarei disso mais a
frente. E método “logout”, lembra que no view
“area_restrita” tem um link que aponto para a action
“logout” do controller “users”?

Portanto temos
criar a action “login” e “logout”, então faremos
isso:

<?php
class UsersController extends AppController {
var $name = 'Users';

function area_restrita(){

}

function login(){

}

function logout(){
$this->redirect($this->Auth->logout()); // Efetuamos logout
}
}
?>

Nós
definimos a action login que fará todas as validações necessárias
automaticamente. E logo após definimos a action responsável por
efetuar logout. Nós utilizamos o método Auth::logout(). Este método
efetua logout e retorna uma string, esta string é o caminho para
onde o usuário deve ir após efetuar logout (por padrão é
“users/login”),
e logo após nos utilizamos o método Controller::redirect() para
mandá-lo para este local. Quando o usuário enviar as informações o
cake automaticamente gerará os hashes das senhas vindas do
formulário, comparará com as da tabela e etc, portanto não é
necessário fazer nada! Nosso sistema já está quase completo, só
falta o view
responsável pelo formulário de login.login.ctp:

<h2>EFETUE LOGIN!</h2>
<?php
$session->flash('auth'); // Exibimos qualquer erro que possa ter ocorrido
echo $form->create('User' , array('action' => 'login'));
echo $form->input('username');
echo $form->input('password');
echo $form->end('LOGAR');
?>

Nosso
pequeno sistema de autenticação está completo. Se você tentar
entrar em algum action sem se autenticar acontecerá o seguinte:

E se tentarmos
inserir informações inválidas:

Opa! Peraí, isso não
está em nosso idioma, vamos fazer algumas modificações em
AppController:

<?php
class AppController extends Controller {
var $name = 'App';
var $components = array('Auth');

function beforeFilter(){
Security::setHash('sha256'); // Setamos o tipo de hash que iremos gerar
$this->Auth->authError = 'Area Restrita! Efetue login!'; // Mensagem ao entrar em area restrita
$this->Auth->loginError = 'Nome de usuario ou senha não conferem!'; // Mensagem quando não se autenticar
}
}
?>

AH! Agora sim, tudo
em português! 

E:

Nosso sistema já está completo, mas passarei
alguns métodos “extras” que podem ser muito úteis em
algumas situações.

Extras

1. Toda vez que você acessa uma action que necessita de autenticação,
o cake armazenará em memória qual era a action que você estava
tentando acessar, para quando você logar-se, ser redirecionado para
tal action. Algumas vezes, quando você vem de um link externo por
exemplo, é necessário setar um caminho padrão, este caminho pode
ser definido pela propriedade Auth::$loginRedirect.

$this->Auth->loginRedirect
= array('action' => 'area_restrita', 'controller' => 'users');

2. O mesmo para logout. Por padrão, ao efetuar logout o metodo
Auth::logout() deixará uma string que indicará o caminho para o
qual o usuário deve ir ao sair. Você também pode alterar pela
propriedade Auth::$logoutRedirect:

$this->Auth->logoutRedirect
= array('action' => 'algumaAction', 'controller' => 'users');

3.
Quando você seta na propriedade $components o que irá utilizar o
componente “Auth”, isso já faz que todas action que o
usuário tentar acessar sejam protegidas, assim redirecionando o
usuário para o local de login. Você pode querer que algumas action
não necessite autenticação, como por exemplo a index do site. É
possível “desprotegê-la” colocando o nome da action no
método Auth::allow(). Veja um exemplo:

$this->Auth->allow('index'
, 'action2' , 'action3');

4. Por padrão o cake assume que você terá um model “User”
que tratará da tabela “users”, é possível alterar isso
também:

$this->Auth->userModel
= 'Usuario';

Também
é possível alterar os nomes dos campos de nome de usuário
(username) e senha (password), basta criar um array associativo para
a propriedade Auth::$fields.

$this->Auth->fields
= array(
'password' => 'senha',
'username' =>
'login'
);

5. Você pode querer, em algum momento de sua aplicação, resgatar
algum dado do usuário, você pode fazer isso com o método
Auth::user(‘nome do campo da tabela’)

$this->Auth->user('idade');

6. Algumas vezes você pode querer fazer alguma validação adicional,
como verificar se o usuário esta marcado como ativo na tabela, você
pode fazer isso utilizando a propriedade Auth::$userScope.

$this->Auth->userScope
= array('User.ativo' => 1);

Ainda
existem muitos outros métodos e propriedades, mas estes são os mais
utilizados. E lembre-se de que os métodos/propriedades referentes à
configuração devem estar dentro do método beforeFilter, porém na
versão 1.3 (ainda não estável) do CakePHP você pode passá-los
como parâmetro no atributo Controller::$components.