Nesta aula, vamos construir um sistema de login completo em PHP, do zero. Você aprenderá na prática como implementar o cadastro de usuários, armazenar senhas de forma segura com hash, gerenciar sessões e proteger rotas que exigem autenticação. Este projeto serve como base para qualquer aplicação web que precise de controle de acesso.

Vamos utilizar PHP orientado a objetos e PDO para acesso a banco de dados, garantindo código limpo e seguro. Ao final, você terá um sistema funcional que pode ser expandido com funcionalidades como recuperação de senha, perfis e níveis de acesso.

Cadastro

O cadastro é a primeira etapa do sistema. Precisamos criar um formulário que receba nome, e-mail e senha, e armazene esses dados no banco de dados. É fundamental validar os dados no servidor para evitar problemas como e-mails duplicados ou senhas fracas.

Vamos criar uma tabela users com os campos: id, name, email, password, e created_at. O campo email deve ser único para evitar duplicidades. No script de cadastro, verificamos se o e-mail já existe antes de inserir.

Exemplo de código para processar o cadastro:

prepare("SELECT id FROM users WHERE email = ?");
        $stmt->execute([$email]);
        if ($stmt->fetch()) {
            $erro = "Este e-mail já está cadastrado.";
        } else {
            // Hash da senha (veremos na próxima seção)
            $hash = password_hash($senha, PASSWORD_DEFAULT);

            // Insere no banco
            $stmt = $pdo->prepare("INSERT INTO users (name, email, password) VALUES (?, ?, ?)");
            $stmt->execute([$nome, $email, $hash]);

            // Redireciona para login
            header('Location: login.php?cadastro=sucesso');
            exit;
        }
    }
}
?>



    Cadastro


    
        




Hash de senha

Armazenar senhas em texto puro é um erro gravíssimo de segurança. Se o banco de dados for comprometido, todas as senhas ficam expostas. Por isso, utilizamos funções de hash, que transformam a senha em uma sequência de caracteres irreversível. O PHP oferece a função password_hash() que gera um hash seguro usando o algoritmo bcrypt (ou mais forte, se disponível).

Para verificar a senha no login, usamos password_verify(), que compara a senha fornecida com o hash armazenado. Nunca tente reverter o hash; a verificação é feita internamente pela função.

Exemplo de hash e verificação:

É importante notar que o hash gerado é único mesmo para a mesma senha, devido ao salt aleatório. Isso dificulta ataques de força bruta e tabelas rainbow.

Sessão

Sessões permitem manter o estado do usuário entre requisições HTTP, que são stateless. Após o login, armazenamos informações do usuário na variável superglobal $_SESSION. O PHP inicia a sessão com session_start() e a mantém através de um cookie de sessão.

No login, após verificar as credenciais, definimos variáveis de sessão como $_SESSION['user_id'] e $_SESSION['user_name']. Para encerrar a sessão (logout), usamos session_destroy() e session_unset().

Exemplo de login com sessão:

prepare("SELECT * FROM users WHERE email = ?");
    $stmt->execute([$email]);
    $user = $stmt->fetch();

    if ($user && password_verify($senha, $user['password'])) {
        // Regenera o ID da sessão para evitar fixação
        session_regenerate_id(true);
        $_SESSION['user_id'] = $user['id'];
        $_SESSION['user_name'] = $user['name'];
        header('Location: painel.php');
        exit;
    } else {
        $erro = "Credenciais inválidas.";
    }
}
?>

É recomendável chamar session_regenerate_id() após o login para prevenir ataques de fixação de sessão.

Proteção de rotas

Proteger rotas significa impedir que usuários não autenticados acessem páginas restritas. A técnica mais simples é verificar se a variável de sessão user_id existe no início de cada página protegida. Se não existir, redirecionamos para a página de login.

Podemos criar um arquivo auth.php que é incluído no topo de cada página protegida. Esse arquivo verifica a sessão e redireciona se necessário.

Exemplo de proteção:

Então, em painel.php, incluímos:





    Painel


    

Bem-vindo, !

Sair

Além disso, podemos usar um roteador (como o do MVC) para centralizar a proteção, mas para este projeto, a inclusão simples é suficiente.

Boas práticas e observações finais

Ao construir sistemas de login, sempre utilize HTTPS em produção para proteger os dados em trânsito. Use htmlspecialchars() ao exibir dados do usuário para evitar XSS. Mantenha as senhas com hash e nunca as envie por e-mail. Considere implementar proteção contra CSRF em formulários e limitar tentativas de login para evitar força bruta.

Este projeto é a base para sistemas mais complexos. Você pode adicionar recuperação de senha, confirmação de e-mail, níveis de acesso e integração com redes sociais.

Referências

Exercícios

  1. Exercício 1: Crie um script PHP que receba um e-mail e senha via POST, e verifique se a senha tem pelo menos 8 caracteres. Se não tiver, exiba uma mensagem de erro. Caso contrário, exiba "Válido".
  2. ✓ Resposta:
  3. Exercício 2: Escreva um código que gere um hash para a senha "123456" usando password_hash e depois verifique se a senha "123456" corresponde ao hash. Exiba o resultado.
  4. ✓ Resposta:
  5. Exercício 3: Crie um script que inicia uma sessão e define as variáveis nome e logado (valor true). Em seguida, exiba o nome da sessão.
  6. ✓ Resposta:
  7. Exercício 4: Crie um arquivo protegido.php que verifica se a sessão está ativa (variável user_id existe). Se não estiver, redirecione para login.php.
  8. ✓ Resposta:
  9. Exercício 5: Implemente um logout simples que destrói a sessão e redireciona para a página de login.
  10. ✓ Resposta: