Conteúdo
Primeiramente, vamos resumir o que será apresentado nessa leitura, você aprenderá a criar e como fazer um sistema de login com PHP e MySQL.
Autenticação dos Usuários
No desenvolvimento web moderno, autenticação de usuários é algo bastante comum e serve como mecanismo de segurança para acessos não autorizados a um ambiente onde somente quem tem cadastro pode entrar, como uma área de membros.
Sistema de Registro
Então, aqui o usuário terá a opção de criar um cadastro preenchendo um formulário, resumindo, se cadastrando. Portanto, o primeiro passo é criar a tabela no banco de dados
Passo 01 – Criar tabela no banco de dados
CREATE TABLE users (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50) NOT NULL UNIQUE,
password VARCHAR(255) NOT NULL,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
Dessa forma, para criar a tabela, basta escolher abrir o PHPMyAdmin e clicar no BD “test” -> SQL (colar o código lá) -> Executar. Conforme imagem abaixo:
Atenção! Descubra os melhores cursos de programação neste guia especial: Cursos de Programação.
Passo 02 – Criação do arquivo de configuração (config.php)
Aqui nós iremos conectar através de um script PHP ao servidor do banco de dados MySQL.
Vamos criar o famoso “config.php” e colocar o devido código dentro dele:
<?php
/* Credenciais do banco de dados. Supondo que você esteja executando o MySQL
servidor com configuração padrão (usuário 'root' sem senha) */
define('DB_SERVER', 'localhost');
define('DB_USERNAME', 'root');
define('DB_PASSWORD', '');
define('DB_NAME', 'test');
/* Tentativa de conexão com o banco de dados MySQL */
try{
$pdo = new PDO("mysql:host=" . DB_SERVER . ";dbname=" . DB_NAME, DB_USERNAME, DB_PASSWORD);
// Defina o modo de erro PDO para exceção
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
die("ERROR: Não foi possível conectar." . $e->getMessage());
}
?>
Nota: Substitua as credenciais de acordo com a configuração do seu servidor MySQL antes de testar este código, por exemplo, substitua o nome do banco de dados ‘test’ pelo seu próprio nome do banco de dados, substitua o nome de usuário ‘root’ pelo seu nome de usuário do banco de dados, especifique a senha do banco de dados, se houver. Caso não faça isso, certifique-se que a tabela tenha sido criado em “test e deixem igual ao exemplo acima sem alterar usuário root ou senha, para fins de aprendizado.
Passo 03 – Vamos criar o formulário de inscrição (register.php)
Aqui vamos criar o arquivo register.php e dentro dele vai ter um script que permitirá que o usuário se registre. Dessa forma, totalmente configurado para gerar mensagens de erro caso usuário não insira nenhum valor ou caso o nome inserido já esteja em uso.
<?php
// Incluir arquivo de configuração
require_once "config.php";
// Defina variáveis e inicialize com valores vazios
$username = $password = $confirm_password = "";
$username_err = $password_err = $confirm_password_err = "";
// Processando dados do formulário quando o formulário é enviado
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Validar nome de usuário
if(empty(trim($_POST["username"]))){
$username_err = "Por favor coloque um nome de usuário.";
} elseif(!preg_match('/^[a-zA-Z0-9_]+$/', trim($_POST["username"]))){
$username_err = "O nome de usuário pode conter apenas letras, números e sublinhados.";
} else{
// Prepare uma declaração selecionada
$sql = "SELECT id FROM users WHERE username = :username";
if($stmt = $pdo->prepare($sql)){
// Vincule as variáveis à instrução preparada como parâmetros
$stmt->bindParam(":username", $param_username, PDO::PARAM_STR);
// Definir parâmetros
$param_username = trim($_POST["username"]);
// Tente executar a declaração preparada
if($stmt->execute()){
if($stmt->rowCount() == 1){
$username_err = "Este nome de usuário já está em uso.";
} else{
$username = trim($_POST["username"]);
}
} else{
echo "Ops! Algo deu errado. Por favor, tente novamente mais tarde.";
}
// Fechar declaração
unset($stmt);
}
}
// Validar senha
if(empty(trim($_POST["password"]))){
$password_err = "Por favor insira uma senha.";
} elseif(strlen(trim($_POST["password"])) < 6){
$password_err = "A senha deve ter pelo menos 6 caracteres.";
} else{
$password = trim($_POST["password"]);
}
// Validar e confirmar a senha
if(empty(trim($_POST["confirm_password"]))){
$confirm_password_err = "Por favor, confirme a senha.";
} else{
$confirm_password = trim($_POST["confirm_password"]);
if(empty($password_err) && ($password != $confirm_password)){
$confirm_password_err = "A senha não confere.";
}
}
// Verifique os erros de entrada antes de inserir no banco de dados
if(empty($username_err) && empty($password_err) && empty($confirm_password_err)){
// Prepare uma declaração de inserção
$sql = "INSERT INTO users (username, password) VALUES (:username, :password)";
if($stmt = $pdo->prepare($sql)){
// Vincule as variáveis à instrução preparada como parâmetros
$stmt->bindParam(":username", $param_username, PDO::PARAM_STR);
$stmt->bindParam(":password", $param_password, PDO::PARAM_STR);
// Definir parâmetros
$param_username = $username;
$param_password = password_hash($password, PASSWORD_DEFAULT); // Creates a password hash
// Tente executar a declaração preparada
if($stmt->execute()){
// Redirecionar para a página de login
header("location: login.php");
} else{
echo "Ops! Algo deu errado. Por favor, tente novamente mais tarde.";
}
// Fechar declaração
unset($stmt);
}
}
// Fechar conexão
unset($pdo);
}
?>
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Cadastro</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<style>
body{ font: 14px sans-serif; }
.wrapper{ width: 360px; padding: 20px; }
</style>
</head>
<body>
<div class="wrapper">
<h2>Cadastro</h2>
<p>Por favor, preencha este formulário para criar uma conta.</p>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<div class="form-group">
<label>Nome do usuário</label>
<input type="text" name="username" class="form-control <?php echo (!empty($username_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $username; ?>">
<span class="invalid-feedback"><?php echo $username_err; ?></span>
</div>
<div class="form-group">
<label>Senha</label>
<input type="password" name="password" class="form-control <?php echo (!empty($password_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $password; ?>">
<span class="invalid-feedback"><?php echo $password_err; ?></span>
</div>
<div class="form-group">
<label>Confirme a senha</label>
<input type="password" name="confirm_password" class="form-control <?php echo (!empty($confirm_password_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $confirm_password; ?>">
<span class="invalid-feedback"><?php echo $confirm_password_err; ?></span>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Criar Conta">
<input type="reset" class="btn btn-secondary ml-2" value="Apagar Dados">
</div>
<p>Já tem uma conta? <a href="login.php">Entre aqui</a>.</p>
</form>
</div>
</body>
</html>
Após a inserção do código, o resultado será igual o da imagem abaixo:
Dessa forma, como no exemplo acima, usamos a função embutida password_hash()
do PHP para criar um hash de senha a partir da string de senha inserida pelo usuário. Portanto, esta função cria um hash de senha usando um algoritmo de hash unilateral forte. Ele também gera e aplica um salt aleatório automaticamente ao fazer o hash da senha; Isso basicamente significa que, mesmo que dois usuários tenham as mesmas senhas, seus hashes de senha serão diferentes.
No momento do login, verificaremos a senha fornecida com o hash de senha armazenado no banco de dados usando a função PHP password_verify()
, conforme demonstrado no próximo exemplo.
Usamos a estrutura do Bootstrap para criar layouts de formulário de maneira rápida e bonita. Por favor, verifique a seção do tutorial do Bootstrap para aprender mais sobre esta estrutura.
Dica: Salting de senha é uma técnica amplamente usada para proteger senhas por meio da randomização de hashes de senha, de forma que, se dois usuários tiverem a mesma senha, eles não terão os mesmos hashes de senha. Dessa forma, isso é feito anexando ou prefixando uma string aleatória, chamada de salt, à senha antes de fazer o hash.
Sistema de Login (login.php)
Aqui o criaremos o formulário de login onde usuário irá inserir suas credenciais cadastradas no formulário de cadastro, login e senha.
Então, ao inserir os dados, as informações inseridas serão verificadas com as informações armazenadas no banco de dados.
Caso os dados estejam certos, o usuário será redirecionado e terá acesso ao sistema, caso os dados não confiram, mensagens de erro serão retornadas para ele.
Passo 01 – Formulário de login
Aqui vamos criar nosso arquivo dentro da pasta raiz do projeto “login.php”.
<?php
// Inicialize a sessão
session_start();
// Verifique se o usuário já está logado, em caso afirmativo, redirecione-o para a página de boas-vindas
if(isset($_SESSION["loggedin"]) && $_SESSION["loggedin"] === true){
header("location: welcome.php");
exit;
}
// Incluir arquivo de configuração
require_once "config.php";
// Defina variáveis e inicialize com valores vazios
$username = $password = "";
$username_err = $password_err = $login_err = "";
// Processando dados do formulário quando o formulário é enviado
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Verifique se o nome de usuário está vazio
if(empty(trim($_POST["username"]))){
$username_err = "Por favor, insira o nome de usuário.";
} else{
$username = trim($_POST["username"]);
}
// Verifique se a senha está vazia
if(empty(trim($_POST["password"]))){
$password_err = "Por favor, insira sua senha.";
} else{
$password = trim($_POST["password"]);
}
// Validar credenciais
if(empty($username_err) && empty($password_err)){
// Prepare uma declaração selecionada
$sql = "SELECT id, username, password FROM users WHERE username = :username";
if($stmt = $pdo->prepare($sql)){
// Vincule as variáveis à instrução preparada como parâmetros
$stmt->bindParam(":username", $param_username, PDO::PARAM_STR);
// Definir parâmetros
$param_username = trim($_POST["username"]);
// Tente executar a declaração preparada
if($stmt->execute()){
// Verifique se o nome de usuário existe, se sim, verifique a senha
if($stmt->rowCount() == 1){
if($row = $stmt->fetch()){
$id = $row["id"];
$username = $row["username"];
$hashed_password = $row["password"];
if(password_verify($password, $hashed_password)){
// A senha está correta, então inicie uma nova sessão
session_start();
// Armazene dados em variáveis de sessão
$_SESSION["loggedin"] = true;
$_SESSION["id"] = $id;
$_SESSION["username"] = $username;
// Redirecionar o usuário para a página de boas-vindas
header("location: welcome.php");
} else{
// A senha não é válida, exibe uma mensagem de erro genérica
$login_err = "Nome de usuário ou senha inválidos.";
}
}
} else{
// O nome de usuário não existe, exibe uma mensagem de erro genérica
$login_err = "Nome de usuário ou senha inválidos.";
}
} else{
echo "Ops! Algo deu errado. Por favor, tente novamente mais tarde.";
}
// Fechar declaração
unset($stmt);
}
}
// Fechar conexão
unset($pdo);
}
?>
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Login</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<style>
body{ font: 14px sans-serif; }
.wrapper{ width: 360px; padding: 20px; }
</style>
</head>
<body>
<div class="wrapper">
<h2>Login</h2>
<p>Por favor, preencha os campos para fazer o login.</p>
<?php
if(!empty($login_err)){
echo '<div class="alert alert-danger">' . $login_err . '</div>';
}
?>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<div class="form-group">
<label>Nome do usuário</label>
<input type="text" name="username" class="form-control <?php echo (!empty($username_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $username; ?>">
<span class="invalid-feedback"><?php echo $username_err; ?></span>
</div>
<div class="form-group">
<label>Senha</label>
<input type="password" name="password" class="form-control <?php echo (!empty($password_err)) ? 'is-invalid' : ''; ?>">
<span class="invalid-feedback"><?php echo $password_err; ?></span>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Entrar">
</div>
<p>Não tem uma conta? <a href="register.php">Inscreva-se agora</a>.</p>
</form>
</div>
</body>
</html>
Após inserir o código do arquivo “login.php” o resultado será igual o da imagem abaixo:
Passo 02 – Página de boas-vindas (welcome.php)
Então, aqui será a página onde usuário será redirecionado ao ter sua credenciais de login validades pelo nosso sistema.
<?php
// Inicialize a sessão
session_start();
// Verifique se o usuário está logado, se não, redirecione-o para uma página de login
if(!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true){
header("location: login.php");
exit;
}
?>
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Bem vindo</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<style>
body{ font: 14px sans-serif; text-align: center; }
</style>
</head>
<body>
<h1 class="my-5">Oi, <b><?php echo htmlspecialchars($_SESSION["username"]); ?></b>. Bem vindo ao nosso site.</h1>
<p>
<a href="reset-password.php" class="btn btn-warning">Redefina sua senha</a>
<a href="logout.php" class="btn btn-danger ml-3">Sair da conta</a>
</p>
</body>
</html>
A página terá essa aparência após o termino do passo acima:
Passo 03 – Script de logout (logout.php)
Dessa forma, agora vamos criar um arquivo “logout.php”. Portanto, quando o usuário clica no link de logout ou logout, o script dentro desse arquivo destrói a sessão e redireciona o usuário de volta para a página de login.
<?php
// Inicialize a sessão
session_start();
// Remova todas as variáveis de sessão
$_SESSION = array();
// Destrua a sessão.
session_destroy();
// Redirecionar para a página de login
header("location: login.php");
exit;
?>
Passo 04 – Página e script para redefinir a senha (reset-password.php)
Então, aqui vamos criar nossa página e script para redefinir a senha. Portanto, vamos criar o arquivo reset-password.php na pasta raiz do nosso projeto e adicionar o seguinte código nele:
<?php
// Inicialize a sessão
session_start();
// Verifique se o usuário está logado, caso contrário, redirecione para a página de login
if(!isset($_SESSION["loggedin"]) || $_SESSION["loggedin"] !== true){
header("location: login.php");
exit;
}
// Incluir arquivo de configuração
require_once "config.php";
// Defina variáveis e inicialize com valores vazios
$new_password = $confirm_password = "";
$new_password_err = $confirm_password_err = "";
// Processando dados do formulário quando o formulário é enviado
if($_SERVER["REQUEST_METHOD"] == "POST"){
// Validar nova senha
if(empty(trim($_POST["new_password"]))){
$new_password_err = "Por favor insira a nova senha.";
} elseif(strlen(trim($_POST["new_password"])) < 6){
$new_password_err = "A senha deve ter pelo menos 6 caracteres.";
} else{
$new_password = trim($_POST["new_password"]);
}
// Validar e confirmar a senha
if(empty(trim($_POST["confirm_password"]))){
$confirm_password_err = "Por favor, confirme a senha.";
} else{
$confirm_password = trim($_POST["confirm_password"]);
if(empty($new_password_err) && ($new_password != $confirm_password)){
$confirm_password_err = "A senha não confere.";
}
}
// Verifique os erros de entrada antes de atualizar o banco de dados
if(empty($new_password_err) && empty($confirm_password_err)){
// Prepare uma declaração de atualização
$sql = "UPDATE users SET password = :password WHERE id = :id";
if($stmt = $pdo->prepare($sql)){
// Vincule as variáveis à instrução preparada como parâmetros
$stmt->bindParam(":password", $param_password, PDO::PARAM_STR);
$stmt->bindParam(":id", $param_id, PDO::PARAM_INT);
// Definir parâmetros
$param_password = password_hash($new_password, PASSWORD_DEFAULT);
$param_id = $_SESSION["id"];
// Tente executar a declaração preparada
if($stmt->execute()){
// Senha atualizada com sucesso. Destrua a sessão e redirecione para a página de login
session_destroy();
header("location: login.php");
exit();
} else{
echo "Ops! Algo deu errado. Por favor, tente novamente mais tarde.";
}
// Fechar declaração
unset($stmt);
}
}
// Fechar conexão
unset($pdo);
}
?>
<!DOCTYPE html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<title>Redefinir senha</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.2/css/bootstrap.min.css">
<style>
body{ font: 14px sans-serif; }
.wrapper{ width: 360px; padding: 20px; }
</style>
</head>
<body>
<div class="wrapper">
<h2>Redefinir senha</h2>
<p>Por favor, preencha este formulário para redefinir sua senha.</p>
<form action="<?php echo htmlspecialchars($_SERVER["PHP_SELF"]); ?>" method="post">
<div class="form-group">
<label>Nova senha</label>
<input type="password" name="new_password" class="form-control <?php echo (!empty($new_password_err)) ? 'is-invalid' : ''; ?>" value="<?php echo $new_password; ?>">
<span class="invalid-feedback"><?php echo $new_password_err; ?></span>
</div>
<div class="form-group">
<label>Confirme a senha</label>
<input type="password" name="confirm_password" class="form-control <?php echo (!empty($confirm_password_err)) ? 'is-invalid' : ''; ?>">
<span class="invalid-feedback"><?php echo $confirm_password_err; ?></span>
</div>
<div class="form-group">
<input type="submit" class="btn btn-primary" value="Redefinir">
<a class="btn btn-link ml-2" href="welcome.php">Cancelar</a>
</div>
</form>
</div>
</body>
</html>
Após o termino do passo acima, a página terá a seguinte aparencia:
Conclusão de sistema de login com PHP e MySQL (PDO)
Portanto, agora temos um sistema de login com PHP e MySQL completinho!
Então, agora vou indicar um curso para você que deseja aprender PHP de forma profissional e construir projetos muito mais complexos, igual ao sistema de login e coisas muito mais complexas, como: Gerenciador de postagens, um painel de controle, uma rede social, sistema com estrutura MVC, clone facebook, um portal de noticias, sistema de gestão de clientes, sistema de gestão de estoque, sistema de gestão de imóveis e MUITO MAIS! Mas é só para quem quer estudar PHP no nível HARD!!!!!!! Link do curso na imagem abaixo:
Conteúdo em vídeo:
Sensacional, parabéns amigão. Acho que só faltou um arquivo para proteger as áreas onde entraremos com o login. Mas acredito quem Welcome.php dá para extrair esse detalhe