Larback - Retornando conhecimento

Um morro nunca desce

Agenda WEB - Parte um - Controle de acesso - Login utilizando PDO

Começaremos o desenvolvimento do nosso sistema de agenda pelo controle de acesso.
Para isso, criaremos no banco de dados uma tabela de usuarios (banco de dados não é o foco desta disciplina, então não entrarei em detalhes e nem discutirei melhorias, ok?)
// No prompt de comando do mysql
// Crie o banco de dados com o comando:
create database agenda;
// Abra o banco de dados
use agenda;
// Crie a tabela de usuários
create table usuarios (usuario varchar(100) primary key, senha varchar(200));
// Insira um usuário para testarmos o login, aqui vou inserir um usuário admin com a senha admin. A senha será criptografada com a função password
insert into usuarios values ('admin',password('admin'));

Com o banco de dados pronto, podemos agora aternos ao PHP.
Nossa primeira página será a index.php - nela criaremos o formulário para login. Para faciliar o designer, utilizaremos bootstrap (se não gosta, mude)
[ARQUIVO: INDEX.PHP]
<!doctype html>
<html lang="pt-br">

<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<title>Agenda Web</title>

</head>
<body>
<form action="login.php" method="post" id="loginform" class="form-horizontal" role="form">
    <div class="container">    
        <div id="loginbox" style="margin-top:50px;" class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">                    
            <div class="panel panel-info" >
                    <div class="panel-heading">
                        <div class="panel-title">Acesso</div>
                        <div style="float:right; font-size: 80%; position: relative; top:-10px"><a href="#">Esqueceu sua senha?</a></div>
                    </div>     

                    <div style="padding-top:30px" class="panel-body" >

                        <div style="display:none" id="login-alert" class="alert alert-danger col-sm-12"></div>
                            
                        
                                    
                            <div style="margin-bottom: 25px" class="input-group">
                                        <span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
                                        <input id="login-username" type="text" class="form-control" name="usuario" value="" placeholder="nome de usuário" requerid>                                        
                                    </div>
                                
                            <div style="margin-bottom: 25px" class="input-group">
                                        <span class="input-group-addon"><i class="glyphicon glyphicon-lock"></i></span>
                                        <input id="login-password" type="password" class="form-control" name="senha" placeholder="senha" required>
                                    </div>
                                    

                                
                            <div class="input-group">

                                <div style="margin-top:10px" class="form-group">
                                    <!-- Button -->

                                    <div class="col-sm-12 controls">
                                      <button type="submit" class="btn btn-success">Login  </button>

                                    </div>
                                </div>


                            </form>     



                        </div>                     
                    </div>  
        </div>        
         </div> 
    </div>
</body>
</html>    
Esta página envia o usuário para a página login.php
A página login.php recebe o usuário e senha enviados via POST, e os envia para o método confere da classe Usuarios. Este método retorna 0 se o usuário e/ou senha estiverem incorretos ou 1 se estiverem corretos. O código da página login é bem simples pois a lógica de acesso ao banco está abstraída na classe Usuario. Se o retorno do método for 1 (usuário e senha corretos), variáveis de sessão são carregadas para a verificação posterior na página principal do sistema. Também o tratamento de possíveis exceções (try/catch) é efetuado nesta página.
[ARQUIVO: LOGIN.PHP]
<?php
session_start();
include_once "Usuario.class.php";
$usuario = new Usuario();
try {
  if($usuario->confere($_POST['usuario'],$_POST['senha'])) {
    $_SESSION['autenticado'] = true;
    $_SESSION['usuario'] = $_POST['usuario'];
    header('location: principal.php');
  } else {
    $_SESSION['autenticado'] = false;
    include_once "index.php";
    exit("<div class='alert alert-danger col-sm-12'>Usuário ou senha incorretos. Verifique</div>");
  }
} catch(PDOException $p){
  echo "Ocorreu um erro inesperado: ". $p->getMessage();
}

?>
A classe Usuario possui a lógica de acesso ao banco de dados mysql utilizando PDO:
[ARQUIVO USUARIO.CLASS.PHP]
<?php
class Usuario {
  const USUARIO = "root";
  const SENHA = "senha_do_banco";
  public function conecta() {
    $con = new PDO("mysql:host=localhost;dbname=agenda", self::USUARIO,self::SENHA);
	  $con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    return $con;
  }
  public function confere($us,$se) {
    $con = $this->conecta();
    $stm = $con->prepare("select * from usuarios where usuario=? and senha=password(?)");
    $stm->bindParam(1,$us);
    $stm->bindParam(2,$se);
    $stm->execute();
    $dados = $stm->fetchAll(PDO::FETCH_ASSOC);
    return count($dados);
     
  }
}
?>
A página principal ainda não está pronta, apenas o nome do usuário atualmente logado é exibido em um layout simples. O acesso não autorizado é negado através da verificação das variáveis de sessão.
[ARQUIVO: PRINCIPAL.PHP]
<?php
session_start();
?>
<!doctype html>
<html lang="pt-br">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

<title>Agenda Web</title>

</head>

<body>
<?php
if (!$_SESSION['autenticado']){
  include_once "index.php";
  exit("<div class='alert alert-danger col-sm-12'>Para acessar o sistema você deve efetuar login</div>");
}
?>
<div class="container">    
        <div id="loginbox" style="margin-top:50px;" class="mainbox col-md-6 col-md-offset-3 col-sm-8 col-sm-offset-2">                    
            <div class="panel panel-info" >
                    <div class="panel-heading">
                        <div class="panel-title">Agenda Web - Bem vindo <b><?=$_SESSION['usuario'];?></b></div>
                        
                        <div style="float:right; font-size: 80%; position: relative; top:-10px"><a href="logout.php"> Sair </a></div>
                    </div>     
            </div>
        </div>
</div>
</body>
</html>
Por último, nesta primeira etapa, criamos um arquivo para logout, onde as variáveis de sessão são destruídas.
[ARQUIVO: LOGOUT.PHP]
<?php
session_start();
unset($_SESSION['autenticado']);
unset($_SESSION['usuario']);
session_destroy();
header("Location: index.php");
?>

Qualquer dúvida, postem no nosso grupo de estudos: https://www.facebook.com/groups/novoid/

Bons estudos.