Olá pessoal, tudo bom? A pedido de algumas pessoas, hoje vou falar como criar um sistema de login bem simples, porém dinâmico, ou seja, vamos fazer a validação sem a necessidade de recarregar a página, utilizando AJAX.
Confira o resultado final aqui (para acessar, utilize as informações que foram inseridas de exemplo)
1. Banco de dados
Inicialmente iremos criar nosso banco de dados:
CREATE TABLE `usuario` ( `usuario_id` INTEGER NOT NULL AUTO_INCREMENT, `login` VARCHAR(28) NOT NULL, `senha` varchar(80) NOT NULL, `nome` varchar(60) NOT NULL, PRIMARY KEY (`usuario_id`) ) ENGINE = MyISAM;
Bem simples, apenas contém uma chave primária (ID), o login, a senha e o nome do usuário. Vamos agora inserir alguns registros de exemplo:
INSERT INTO usuario VALUES (1, 'admin', 'admin', 'Administrador'); INSERT INTO usuario VALUES (2, 'rafael', 'couto', 'Rafael Couto Alves'); INSERT INTO usuario VALUES (3, 'foo', 'bar', 'Fulano');
2. Formulário de login (index.html)
Vamos criar a aparência da nossa página de login:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>Entrar</title> </head> <body> <form id="frmLogin" action="ajax/logar.php" method="post"> <fieldset> <legend>Entrar</legend> <div class="loader" style="display: none;"><img src="image/loader.gif" alt="Carregando" /></div> <div class="mensagem-erro"></div> <p> <label for="login">Usuário</label> <br /> <input type="text" id="login" name="login" /> </p> <p> <label for="senha">Senha</label> <br /> <input type="password" id="senha" name="senha" /> </p> <input type="submit" value="Entrar" /> </fieldset> </form> </body> </html>
Nada de mais, é apenas um formulário HTML com dois campos, login e senha, e um botão de submit. No cabeçalho (head) de nossa página, vamos incluir uma biblioteca e um plugin javascript:
<script type='text/javascript' src='js/jquery.js'></script> <script type='text/javascript' src='js/jquery.form.js'></script>
- Linha 1: incluindo a biblioteca indispensável: jQuery.
- Linha 2: incluindo um plugin para jQuery, o jQuery Form. Ele facilita a requisição AJAX, pois não precisamos pegar e passar cada campo (como é feito nesse artigo, por exemplo), o plugin já faz este trabalho pela gente.
3. jQuery (index.html)
Nessa parte, vamos recuperar as informações do formulário e enviar para a página PHP. Adicione o seguinte código no cabeçalho de nossa index.html:
// Quando carregado a página $(function($) { // Quando enviado o formulário $('#frmLogin').submit(function() { // Limpando mensagem de erro $('div.mensagem-erro').html(''); // Mostrando loader $('div.loader').show(); // Enviando informações do formulário via AJAX $(this).ajaxSubmit(function(resposta) { // Se não retornado nenhum erro if (!resposta) // Redirecionando para o painel window.location.href = 'painel.php'; else { // Escondendo loader $('div.loader').hide(); // Exibimos a mensagem de erro $('div.mensagem-erro').html(resposta); } }); // Retornando false para que o formulário não envie as informações da forma convencional return false; }); });
Vamos analisar o código:
- Linha 5: Aplicamos o evento submit no formulário (#frmLogin), ou seja, assim que o usuário clicar em entrar este método será chamado.
- Linha 14: Através do método ajaxSubmit() do nosso plugin, as informações do formulário são enviadas para seu action (logar.php), através do método definido no formulário, no caso, POST. Isso é o equivalente ao .post() nativo do jQuery, porém o plugin já captura e envia as informações para nós;
- Linha 17: Verificamos se a resposta retornada pelo nosso logar.php é falsa, ou seja, 0;
- Linha 19: Se a resposta for falsa, significa que o login deu certo, portanto redirecionamos o usuário para seu painel (painel.php);
- Linha 26: Se o login não deu certo, colocamos a mensagem retornada pelo logar.php na div cujo a classe é mensagem-erro;
- Linha 32: Precisamos retornar false para que o formulário não seja enviado, pois nós já enviamos as informações e recebemos a resposta via AJAX.
4. Conexão e configuração (config/conn.php)
Aqui vamos criar nosso arquivo para fazer a conexão com o banco de dados, nesse arquivo também vamos criar um método para carregar automaticamente a classe de login que veremos adiante.
<?php // Informações para conexão $host = 'localhost'; $usuario = 'root'; $senha = 'senha'; $banco = 'banco'; // Realizando conexão e selecionando o banco de dados $conn = mysql_connect($host, $usuario, $senha) or die(mysql_error()); $db = mysql_select_db($banco, $conn) or die(mysql_error()); // Definindo o charset como utf8 para evitar problemas com acentuação $charset = mysql_set_charset('utf8'); // Função para carregar a classe automaticamente, quando instanciado um objeto function __autoload($class) { require_once(dirname(__FILE__) . "/../class/{$class}.class.php"); } ?>
5. Logando (ajax/logar.php)
Este arquivo será responsável por fazer criar o login do usuário. Para facilitar e diminuir muitas linhas de código eu criei uma classe simples (a classe deste artigo foi melhorada, porém os métodos são os mesmos) para fazer a ações básicas de um login. Portanto, nosso código fica da seguinte maneira:
<?php // Incluindo arquivo de conexão/configuração require_once('../config/conn.php'); // Instanciando novo objeto da classe Login $objLogin = new Login(); // Recuperando informações enviadas $login = $_POST['login']; $senha = $_POST['senha']; // Se conseguir encontrar o usuário e a senha estiver correta if ($objLogin->logar($login, $senha)) // Retornando falso, ou seja, esta tudo certo echo false; else // Retornando mensagem de erro echo 'Login ou senha inválidos'; ?>
Repare que não foi necessário incluir o arquivo da classe Login, pois no arquivo de configuração (config/conn.php) foi definida a função __autoload(), ou seja, assim que o objeto $objLogin é criado, o __autoload() se encarrega de incluir o arquivo da classe, porém o arquivo da classe deve seguir o padrão: Classe.class.php.
Vamos a alguns detalhes:
- Linha 6: Criamos um objeto da nossa classe Login. Por padrão a tabela é usuario, a chave primária é usuario_id, o campo login é login e o campo senha é senha. Porém, poderíamos definir outras informações passando os parâmetros do construtor, exemplo:
$objLogin = new Login('tb_usuarios', 'codigo', 'campo_login', 'campo_senha');
- Linha 13: O método logar() aceita um terceiro parâmetro que é para onde o usuário será redirecionado se o login e senha estiverem corretos, no caso, isso não nos interessa, pois esta é uma página que será recebida pela requisição AJAX, portanto o método irá apenas retornar true, se as informações estiverem corretas, ou, caso contrário, false.
6. Painel do usuário (painel.php)
Esta é uma das página da qual apenas um usuário que esteja logado terá acesso, para isso, precisamos apenas verificar se o usuário está logado:
<?php // Incluindo arquivo de conexão/configuração require_once('config/conn.php'); // Instanciando novo objeto da classe Login $objLogin = new Login(); // Verificando se o usuário está logado, caso contrário será redirecionado para a página de login if (!$objLogin->verificar('index.html')) // Finalizado o script, apenas para garantir que o usuário não irá ver o conteúdo da página exit; ?>
Depois que reconhecido que o usuário está logado. podemos recuperar o ID e o login do usuário que estão na sessão, através do objeto de login, por exemplo:
<?php echo "ID: {$objLogin->getID()} <br />"; echo "Login: {$objLogin->getLogin()}"; ?>
Tendo o ID, podemos recuperar todas as suas informações, fazendo um simples SELECT:
// Selecionando informações do usuário $query = mysql_query("SELECT * FROM usuario WHERE usuario_id = {$objLogin->getID()}"); $usuario = mysql_fetch_object($query);
Sendo assim, podemos mostrar as informações que não estão na sessão:
echo "Bem vindo {$usuario->nome}";
7. Logout (sair.php)
Para finalizar a sessão é muito simples:
<?php // Incluindo arquivo de conexão/configuração require_once('config/conn.php'); // Instanciando novo objeto da classe Login $objLogin = new Login(); // Finaliza a sessão e redireciona o usuário para a página de login $objLogin->logout('index.html'); ?>
8. Finalizando
Bom pessoal, por hoje é isso, tentei detalhar o máximo possível, mas não houve tempo para explicar sobre a estrutura da classe, nem alguns detalhes sobre a programação orientada a objetos, isto fica para uma próxima, ok?
Espero que vocês tenham entendido e que a idéia seja útil para vocês.
Qualquer dúvida, sugestão ou critica construtiva, deixe um comentário ou envie um email.
Até a próxima, abraços.