Login dinâmico com JQuery/PHP/MySQL

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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<!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:

1
2
<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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
// 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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<?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:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?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:

1
2
3
// 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?

Download dos arquivos

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.

17 comments

  1. Rafael, gostaria de parabeniza-lo não só por este post mas sim por todo seu blog.
    Cheguei até seu site procurando um sistema (meio pronto) para login no google, e acabei achando este maravilhoso post.
    Apos isto, percebi que em seu blog tem VARIAS coisas que serão MUITO UTEIS pra mim.
    Muito obrigado e novamente meus parabens.

  2. Olá Rafael,

    Pode me ajudar? está dando erro quando sou direcionado para a pagina painel.php

    Warning: mysql_fetch_object(): supplied argument is not a valid MySQL result resource in C:\xampp\htdocs\upload\login\painel.php on line 15

    // Selecionando informações do usuário
    $query = mysql_query(“SELECT * FROM usuario WHERE usuario_id = {$objLogin->getID()}”);
    $usuario = mysql_fetch_object($query);

    • Olá Ricardo,

      Provavelmente há alguma problema na sua SELECT, você utilizou a mesma estrutura de banco do artigo? Tente rodar o comando SQL no phpMyAdmin (por exemplo) e veja se está funcionando, ou tente assim:

      $query = mysql_query("SELECT * FROM usuario WHERE usuario_id = {$objLogin->getID()}") or die(mysql_error());
      $usuario = mysql_fetch_object($query);

      Desse modo ele vai mostrar a mensagem de erro, e então descobrimos o problema.
      Abraço.

  3. Parabéns pelo ótimo tutorial, era o que eu estáva precisando foi mesmo de grande ajuda! Só uma dúvida: Como faço para colocar um nivel de acesso para cada página? criei um campo no banco onde pode-se ter o nível 1 e 2 não consigo implementar isso no Login.class. Se puder me ajudar ficarei eternamente grato.

  4. Cara, quando eu tenho mais de um usuário cadastrado no banco e atualizo a página o usuário muda. Parece q a SESSION não grava. Pode me ajudar? Tô usando a tua class.

  5. Parabens pelo tutorial, era o que estava precisando, ha muito tempo estava procurando um codigo completo como este que pudesse me ajudar a implementar no meu projeto.

    So uma dúvida exite alguma outra maneira de fazer a consulta no banco sem criar a classe login?
    No meu projeto nao estou usando POO.

    Abraço

    • Olá Max,

      Obrigado.
      Não tem importância, você pode incluir (include) a classe no seu arquivo .php e usar os métodos dela, independente se seu projeto é POO ou estruturado.

      Abraço.

  6. Estou com um problema… Quando acesso a página do sistema que é protegida com Login, em duas abas no Browser e ao clicar em sair do sistema em uma das abas… E em seguida ao acessar a Aba que continua com o sistema aberto… (Para utilizar alguma de suas aplicações) A página de Login é carregada em uma Div dentro da própria pagina *Protegida… :/ O correto é a pagina Atual ser substituída pela página de login.php e não o mesmo ser carregado dentro da pagina Protegida..

    Para redirecionar estou utilizando: header(‘Location: login.php’);

    Como posso resolver esse problema?
    Obrigado pelas Dicas…

  7. Rafael gostaria de entender melhor a variavel $redireciona na classe.Login , entendi que ela é uma boolean porém nao entendi o funcionamento exatamente.

    Por exemplo:

    function logar($login, $senha, $redireciona = null) ela ja recebe null

    e dai por diante é feita a consulta no banco, se encontra usuario é instaciado e registramos a sessão logo após….

    if ($redireciona !== null)

    header(“Location: {$redireciona}”); qual o valor de $redireciona aqui neste momento ? para onde o location vai enviar o usuario?

    else
    return true;

    ela se repete mais na frente em outros metodos, mas pelo que vi minha duvida é como ela funciona e qual o valor guardado nela que direciona para outro caminho?

    Mais uma vez agradeço desde já a atenção

    Abraço

    Max.

Deixe um Comentário

O seu endereço de email não será publicado Campos obrigatórios são marcados *

*

Você pode usar estas tags e atributos de HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre lang="" line="" escaped="" highlight="">