JAMES WEB

Aprenda como se faz.


Sumário

Acessando a página administrativa

Ao acionar o hiperlink ‘Login’ na página principal, o usuário é direcionado para a interface de autenticação. Nela, ao inserir as credenciais (nome de usuário e senha), o sistema consulta o banco de dados para validar a autenticidade das informações fornecidas. Caso a validação seja bem-sucedida, o usuário é redirecionado para a área administrativa, onde poderá executar as tarefas pertinentes. Vamos preparar os recursos para isto acontecer.

administrador

Criando Rota Login_post – Página Administrativa

Vamos criar a rota que vai possibilitar o acesso a área administrativa do sistema. Para isto, utilizando o Editor de Texto (Sublime-text), acesse o arquivo admin.php e crie uma nova rota acrescentando o seguite código:

admin.php

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
<?php
// Inicio código ...
 
//Rota Login_post Página Administrativo (login_post)
$app->post('/admin/login_post'function() {       
  try {
  $user = User::login($_POST["login"], $_POST["password"]);
  if ($user) {
    // Usuário logado com sucesso
    header("Location: /ecommerce/admin");
    else {
      // Exibir mensagem de erro          
      echo '<script>
        function mostrarAlertaERedirecionar() {
        return new Promise(resolve => {
        alert("Usuário inexistente ou senha inválida!");
        resolve();
        });
      }
      mostrarAlertaERedirecionar().then(() => {
      window.location.href = "/ecommerce/admin/login_get";
      });
      </script>'; 
    }
  catch (\Exception $e) {
  // Tratar outras possíveis exceções
  echo "Ocorreu um erro: " $e->getMessage();
  }
  exit;
});
 
//... Final código
?>

Este código implementa a lógica de autenticação de usuários em uma aplicação web. Quando um usuário tenta fazer login, as credenciais são enviadas via POST para esta rota. O código verifica as credenciais no banco de dados e, se forem válidas, redireciona o usuário para a área administrativa. Caso contrário, exibe uma mensagem de erro e redireciona o usuário de volta para a página de login.

Explicando o trecho do código:

  • L5 – $app->post(‘/admin/login_post’, function() {:
    Esta linha define uma rota POST para a URL /admin/login_post. Ou seja, quando um formulário HTML com o método POST for enviado para essa URL, o código dentro da função será executado.
  • L6 – try {:
    Inicia um bloco try, que é utilizado para capturar possíveis exceções que possam ocorrer durante a execução do código dentro desse bloco.
  • L7 – $user = User::login($_POST[“login”], $_POST[“password”]);:
    Chama um método estático login da classe User, passando os valores de login e password obtidos do formulário POST. Este método consulta o banco de dados para verificar se as credenciais são válidas e retorna um objeto User se forem válidas, ou null caso contrário. Veja em “Criando a Classe User” a inserção do método estático login.
  • L8 – if ($user) {:
    Verifica se o método login retornou um objeto User. Se sim, significa que o usuário foi autenticado com sucesso.
  • L10 – header(“Location: /ecommerce/admin”);:
    Redireciona o usuário para a página /ecommerce/admin, que é a página principal da área administrativa. Veja e crie a rota necessária em “Criando Rota Administrativa”,
  • L11 – } else {:
    Se o usuário não foi autenticado, entra neste bloco.
    Código JavaScript: Este bloco de código JavaScript é utilizado para exibir um alerta informando que o usuário ou a senha estão inválidos e, em seguida, redireciona o usuário de volta para a página de login.
  • L20 – mostrarAlertaERedirecionar(){…}
    Uma função JavaScript que cria uma Promise para exibir o alerta e, em seguida, redireciona a página.
  • L21 – window.location.href = “/ecommerce/admin/login_get”;:
    Redireciona o usuário para a página /ecommerce/admin/login_get, que é o Formulário de Autênticação com o método GET.
  • L25 – catch (\Exception $e) {:
    Captura qualquer exceção que possa ocorrer durante a execução do código dentro do bloco try. A mensagem de erro da exceção é exibida para o usuário.
  • L29 – exit;:
    Encerra a execução do script após o tratamento da requisição.

Criando Classe User

A classe User é responsável pela autenticação de usuários. Ela possui métodos para realizar o login, verificar a sessão do usuário e efetuar o logout. A classe utiliza a classe Sql para interagir com o banco de dados e armazena informações do usuário logado em uma sessão.

Antes de criar a classe User, acesse o arquivo index.php onde utilizamos propriedades e métodos relacionados a um usuário, como nome, email, senha, etc. Por issto temos de inserir no início do arquivo a linha use \Hcode\Model\User; que informa ao PHP que você quer utilizar a classe User, que se encontra dentro da pasta Model dentro do namespace Hcode. Ao fazer isso, você pode criar instâncias dessa classe e utilizar seus métodos em outras partes do seu código, sem precisar especificar o caminho completo até o arquivo da classe. Veja como editar o arquivo:

1
2
3
4
5
6
7
8
9
10
11
<?php
 
require_once("vendor/autoload.php");
 
use \Slim\Slim;
use \Hcode\Page;
use \Hcode\PageAdmin;
use \Hcode\Model\User;
 
// resto do código
?>

Para criar a classe User temos de navegar pelas pastas ecommerce > vendar > hcodebr > php-classes > src. Dentro da pasta src crie a pasta Model e dentro desta o arquivo user.php. Veja o arquivo a seguir: onde criaremos o método estático login.

user.php

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
<?php
 
namespace Hcode\Model;
use \Hcode\DB\Sql;
use \Hcode\Model;
 
class User extends Model {
 
  const SESSION = "User";
 
  public static function login($login$password) {
    $sql new Sql();
    $results $sql->select("SELECT * FROM tb_users 
      WHERE deslogin = :LOGIN", array(
      ":LOGIN" => $login
    ));
 
    if (count($results) === 0) {
      return false;
    }
 
    $data $results[0];
 
    if (password_verify($password$data["despassword"]))
    {
      $user new User();
      $user->setData($data);
      $_SESSION[User::SESSION] = $user->getValues();
      return $user
    else {
      return false;
    }
  }
   
?>

Explicação Linha a Linha Classe User (método estático login):

  • L3 – namespace Hcode\Model;:
    Esta linha define um namespace chamado Hcode\Model. Um namespace é utilizado para organizar classes e evitar conflitos de nomes. Todas as classes definidas dentro desse arquivo pertencerão ao namespace Hcode\Model. Veja em mais “Criando a Classe Model”
  • L4 – use \Hcode\DB\Sql;:
    Importa a classe Sql do namespace Hcode\DB. Isso permite usar a classe Sql diretamente sem precisar especificar o namespace completo. A classe Sql faz a conexão com o bando de dados.
  • L5 – use \Hcode\Model;:
    Essa linha permite usar a classe Model (que deverá ser criada).
  • L7 – class User extends Model {:
    Define a classe User que herda da classe Model. Isso significa que a classe User tem acesso a todas as propriedades e métodos da classe Model.
  • L9 – const SESSION = “User”;:
    Define uma constante estática chamada SESSION com o valor “User”. Essa constante é utilizada para armazenar informações do usuário em uma sessão.
  • L11 – public static function login($login, $password) {:
    Define uma função estática chamada login que recebe dois parâmetros: $login e $password. A palavra-chave static indica que o método pode ser chamado sem criar uma instância da classe User.
  • L12 – $sql = new Sql();:
    Cria uma nova instância da classe Sql para realizar operações de banco de dados.
  • L13 – $results = $sql->select(…):
    Executa uma consulta SQL para buscar o usuário com o login fornecido. O resultado da consulta é armazenado na variável $results.
  • L18 – if (count($results) === 0) { … }:
    Verifica se não foi encontrado usuário com o login fornecido. Se não houver resultado, a função retorna false. Isto faz que seja exibida a mensagem de erro: “Usuário inexistente ou senha inválida”.
  • L22 – $data = $results[0];:
    Insere dentro da variável $data os dados do primeiro usuário encontrado.
  • L24 – if (password_verify($password, $data[“despassword”])) { … }:
    Verifica se a senha fornecida corresponde à senha armazenada no banco de dados usando a função password_verify. Se a senha estiver correta, cria um objeto User, preenche seus dados e armazena o usuário em uma sessão que é criada em $_SESSION[User::SESSION] = $user->getValues(), que retorna os atributos objeto User. Caso contrário, retorna false e exibindo a mensagem de erro: “Usuário inexistente ou senha inválida” .

Observe que para ter uma sessão precisamos iniciá-la. Isto é feito no arquivo index.php. Portanto acesse o referido arquivo e adicione logo no inicio a linha session_start();. Veja o exemplo a seguir:

1
2
3
4
5
6
7
8
<?php
 
session_start();
require_once("vendor/autoload.php");
 
//… resto do código
 
?>

Criando Classe Model

A classe User extende da classe Model. Portanto temos de criá-la. Navegue pelas pastas ecommerce > vendar > hcodebr > php-classes > src. Dentro da pasta src crie o aquivo Model.php. Esta classe é utilizada pela classe User para manipular dados. A classe utiliza um método mágico __call para permitir acesso dinâmico às propriedades do objeto.

model.php

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
36
37
38
39
40
<?php
 
namespace Hcode;
 
class Model {
 
  private $values = [];
 
  public function __call($name$args){
 
    $method substr($name, 0, 3);
    $fieldName substr($name, 3, strlen($name));
 
    switch ($method)
    {
      case "get":
        return $this->values[$fieldName];
      break;
         
      case "set":
        $this->values[$fieldName] = $args[0];
      break;
    }
 
  }
 
  public function setData($data array())
  {
    foreach ($data as $key => $value) {   
      $this->{"set".$key}($value);
    }
  }
 
  public function getValues()
  {
    return $this->values;
  
}
 
?>

A classe Model fornece uma estrutura básica para outros modelos, implementando getters e setters dinâmicos e um método para atribuir um conjunto de valores ao modelo. Isso simplifica a manipulação de dados e a interação com o banco de dados em uma aplicação MVC.

Veja a explicação da classe Model linha a linha:

  • L3 – namespace Hcode;:
    Define o namespace Hcode para organizar as classes do projeto.
  • L7 – private $values = [];:
    Declara uma propriedade privada $values como um array vazio. Essa propriedade será usada para armazenar os dados do usuário.
  • L9 – public function __call($name, $args){:
    Define o método mágico __call. Esse método é chamado quando um método não existe no objeto. Os parâmetros $name e $args contém o nome do método chamado e os argumentos passados.
  • L11- $method = substr($name, 0, 3);:
    Extrai os primeiros três caracteres do nome do método chamado ($name) utilizando funções de string e armazena em $method. Isto determinará se o método e set ou get.
  • L12- $fieldName = substr($name, 3, strlen($name));:
    Extrai os caracteres restantes do nome do método e armazena em $fieldName.
  • L14- switch ($method):
    Verifica o valor de $method e executa o código correspondente.
  • L16- case ‘get’::
    Se $method for “get“, retorna o valor da propriedade correspondente a $fieldName armazenado em $values.
  • L20- case ‘set’::
    Se $method for “set“, atribui o primeiro argumento à propriedade correspondente a $fieldName em $values.
  • L18 e 22- break:
    Interrompe o ciclo da switch.
  • L27- public function setData($data = array()):
    Define uma função setData que recebe um array opcional $data como parâmetro. O método setData cria dinâmicamente atributos com valores para todos os campos retornado do banco de dados
  • L29- foreach ($data as $key => $value) { … }:
    Itera sobre o array $data, atribuindo cada valor ao respectivo campo do objeto usando o método mágico set.
  • L34- public function getValues():
    Define a função getValues que retorna o array $values contendo todos os valores armazenados no objeto.

Criando Rota Administrativa

Quando o login é efetuado com sucesso, isto é, usuário e senha são confirmados, samos direcionados para a página administrativa. É o que sugere a linha 10 header(“Location: /ecommerce/admin”); da “Rota Login_post” no arquivo admin.php.

Para isto é necessário criar a “Rota Página Administrativa”. Portanto com o uso do Sublime-text, acesse o arquivo admin.php e insira o seguinte código:

admin.php

1
2
3
4
5
6
7
8
9
10
11
12
<?php
// ... inicio código 
 
//Rota Página Administrativa
$app->get('/admin'function() {
  User::verifyLogin();
  $page new PageAdmin();
  $page->setTpl("index");
});
 
// ... Resto do código
?>

Este código define uma rota para a área administrativa e garante que apenas usuários autenticados possam acessá-la. A página da área administrativa será renderizada utilizando o template “index.html” da pasta views/admin.

Veja como funciona a Rota Página Administrativa linha por linha:

  • L3 – $app->get(‘/admin’, function() {:
    • $app->get():
      Define uma rota GET para a URL localhost/ecommerce/admin. Isso significa que quando um usuário acessar a URL /admin em seu navegador, o código dentro da função anônima será executado.
    • /admin:
      É o caminho da URL que aciona essa rota.
    • function() {:
      Inicia uma função anônima, que é o bloco de código que será executado quando a rota for acessada.
  • L6 – User::verifyLogin();:
    Chama um método estático chamado verifyLogin() da classe User. Este método verifica se o usuário está autenticado (logado) no sistema. Se o usuário não estiver logado, esse método redireciona o usuário para a página de login.
  • L7 – $page = new PageAdmin();:
    Cria uma nova instância de uma classe chamada PageAdmin. Essa classe é responsável por renderizar a página da área administrativa.
  • L8 – $page->setTpl(“index”);:
    Chama o método setTpl() da classe PageAdmin (extendida da Classe Page), passando o parâmetro “index”. Este método define o template (modelo) que será utilizado para renderizar a página. O valor “index” indica que o template a ser utilizado é o template “index.html”.

Criando Método verifyLogin()

Na linha 6 no código da Rota Página Administrativa do arquivo admin.php é chamada o método verifyLogin da Classe User que verifica se o usuário está logado no sistema e assim permitir que ele acesse a Página Administrativa.

Acesse via Sublime-text o arquivo User.php e acrescente o trecho de código correspondente ao método verifyLogin, como no exemplo a seguir:

user.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?php
// ... inicio código 
 
public static function verifyLogin($inadmin = true)
  {
    if (
      !isset($_SESSION[User::SESSION])
      ||
      !$_SESSION[User::SESSION]
      ||
      !(int)$_SESSION[User::SESSION]["iduser"] > 0
      ||
      (bool)$_SESSION[User::SESSION]["inadmin"] !== $inadmin
        ) {
 
      //header("Location: /admin/login");
      header("Location: /admin/login");
      exit;
    }
  }
 
// ... Resto do código
?>

O método verifyLogin() verifica se o usuário está autenticado e, se necessário, se possui permissão de administrador. Ele verifica a existência da sessão, a validade do ID do usuário e a permissão de administrador. Se alguma dessas condições não for atendida, o usuário é redirecionado para ao Formulário de Autênticação.

Veja como o método verifyLogin funciona linha por linha:

  • L4 – public static function verifyLogin($inadmin = true):
    • public static:
      Indica que o método é público e pode ser acessado de fora da classe.
    • function verifyLogin($inadmin = true):
      Define o nome do método como verifyLogin e declara um parâmetro opcional $inadmin com o valor padrão de true.
  • L6 – if (…) {:
    Inicia uma condição condicional para verificar se o usuário está logado e possui as permissões necessárias.
  • L7 – !isset($_SESSION[User::SESSION]):
    Verifica se a sessão do usuário está definida. Se não estiver definida, significa que o usuário não está logado.
  • L8 e 9 – || !$_SESSION[User::SESSION]:
    Ou verifica se o valor da sessão é diferente de null. Isso é uma medida adicional para garantir que a sessão esteja válida.
  • L10 e 11 – || !(int)$_SESSION[User::SESSION][“iduser”] > 0:
    Ou verifica se o ID do usuário armazenado na sessão é um número inteiro positivo. Se não for, significa que o usuário não está logado ou que os dados da sessão estão inválidos.
  • L12 e 13 – || (bool)$_SESSION[User::SESSION][“inadmin”] !== $inadmin:
    Ou verifica se a permissão de administrador do usuário armazenada na sessão é igual ao valor do parâmetro $inadmin. Isso permite controlar se o método deve verificar apenas usuários administradores ou todos os usuários.
  • L16 – header(“Location: /admin/login”);:
    Se alguma das condições acima for verdadeira, significa que o usuário não está logado ou não possui as permissões necessárias. Portanto, o usuário é redirecionado para a Formulário de Autênticação.
  • L18 – exit;:
    Encerra a execução do script após o redirecionamento.

Template Página Administrativa

No Formulário de Autênticação, quando inserimos os dados e clicamos em “Sign in” e o usuário é autenticado, somos direcionados par página de administração. Para isto temos de confirgurá-la em nosso projeto.

Utilizaremos um Modelo Pronto Para agilizar o processo bem popular chamado AdminLTE. Faça o download dos arquivos dele no site https://adminlte.io/themes/v3/ e baixe o tema “Template-admin“.

Organizando os Arquivos

  • Abra o seu projeto da loja e crie uma nova pasta chamada “admin” dentro da pasta “res”.
  • Copie todos os arquivos que você baixou do AdminLTE para dentro dessa nova pasta “admin”.
  • Dentro da pasta “admin” crie novos arquivos “header, footer e index.html” para criarmos o template admin.
  • Acesse o arquivo “starter.html” no sublime-text (103 – configurando Template do Admin – AdminTE 2.3.aa – Started). Esse será o nosso ponto de partida para o painel administrativo.
  • Selecione e cole (ctrl + x) da linha 278 “<!– Content Wrapper. Contains page content –>” até a linha 300 “<!– /.content-wrapper –>”, que corresponde ao conteúdo da página.
  • Abra o arquivo index.php da pasta admin e copie (ctrl + v) o arquivo.
  • Voltando no arquivo “start.html” selecione e recorte (ctrl + x) da linha 1 “<!DOCTYPE html>” até a linha 276 “” e copie (ctrl + v) no arquivo header.html da pasta admin.
  • Por fim, ainda no arquivo start.html, selecione e recorte (ctrl + x) o restante do código da linha 302 “<!– Main Footer –>” até a linha 405 “</html>” e cole (ctrl +v) no arquivo footer.html do pasta admin.

Nos arquivos editados “header.html” temos que editar o link nos “href” local. Não edite os “href” que iniciarem em https… como no exemplo abaixo ou os href=”#”:

href = “https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.5.0/css/font-awesome.min.css”>

Para facilitar use o sublime-text para editar os caminhos com um (ctrl +h) coloque em (find what) (href=”) e em (replace with) (href=”/res/admin/”). Clique em (find) e troque somente o links locais (replace).

Temos que fazer o mesmo procedimento para (src=”…). Troque o links locais de (src=”) por (src=”/res/admin/”).

Caso tenham dificuldade, diponbilizamos para download os arquivos header, index e footer.html para o dministrativo.

Se tudo der certo, você visualizar algo parecido com isto:

template-admin

Um detalhe importante é que solicitamos renderizar o arquivo index.html via a Classe PageAdmin. Mas esta classe herda as propriedade da Classe Page, que verifica se as opções de header e footer são verdadeiros. Caso sejam as respectivas partes são renderizadas em seu tempo.

Se você está tendo problemas com os arquivos do template, localize os arquivos header, footer e index.html já prontos para uso na pasta dos arquivos baixados.

Criando Rota Logout – Página Administrativo

Uma vez acessando a Página Administrativa, vamos habilitar o botão “Sign Out” que surge na aba quando clicamos no usuário logado no menu no canto superior direito. Para isto temos de criar uma nova rota (Rota Sair Administrativo) no arquivo admin.php.

PHP: admin.php

1
2
3
4
5
6
7
8
9
10
11
12
<?php
// ... início do código 
 
//Rota Sair administrativo (sign_out) 
$app->get('/admin/sign_out'function() {
        User::logout();
        header("Location: /ecommerce/");
        exit;
    });
 
// resto do código ...
?>

Explicando o códigoda Rota Sair Administrativo:

  • L5 – $app->get(‘/admin/sign_out’, function() {
    Esta linha define uma rota GET para a URL /admin/sign_out. Isso significa que quando esta rota e acionada, o código dentro da função anônima será executado.
  • L6 – User::logout():
    Chama o método logout() da classe User. Este método, é responsável por: remover os dados do usuário da sessão (como nome, email, ID, etc.), invalidar qualquer token de acesso que o usuário possa ter, realizar outras ações necessárias para deslogar o usuário do sistema.
  • L7 – header(“Location: /ecommerce”);:
    Informa ao navegador que ele deve redirecionar o usuário para a URL /ecommerce. Após a execução desta linha, o navegador automaticamente carregará a página principal.

Método logout()

Para atender a linha 6 User::logout() da “Rota Sair Administrativo” temos de criar o método correspondente. Para isto, abra o arquivo User.php e insira o trecho a seguir:

PHP: user.php

1
2
3
4
5
6
7
8
9
10
<?php
// ... início do código
 
public static function logout()
{
  $_SESSION[User::SESSION] = NULL;
}
 
// resto do código ...
?>

O método logout() remove os dados do usuário da sessão, efetivamente deslogando o usuário da aplicação. Após a execução desse método, o usuário será considerado não autenticado e não terá mais acesso às áreas restritas da aplicação.

Para efetuar o logout, vamos utilizar o arquivo login.html que corresponde a página administrativa. Ele está na pasta admin.

  • Abra o arquivo login.html no editor de texto;
  • Procure a linha href=”#” class=”btn btn-default btn-flat”>Sign out…;
  • No href=”#” altere para href=”http://localhost/ecommerce/admin/sign_out”

Resumo

Neste módulo, foram definidas as rotas de acesso à área administrativa do sistema. A rota de login foi implementada, permitindo a autenticação dos usuários. Embora a interface administrativa ainda não tenha sido desenvolvida, a estrutura básica para a validação das credenciais já está estabelecida.

A rota administrativa utiliza o método login da classe User para verificar a autenticidade dos dados fornecidos pelo usuário. A classe User, que estende a classe Model, facilita a manipulação dos dados do usuário e a interação com o banco de dados.

No próximo módulo, será configurado o template da área administrativa, possibilitando a realização de operações como cadastro, edição e exclusão de usuários, categorias e produtos.

Arquivos para download:

Para saber mais:

  • Model
  • namespace
  • Sessão
  • Metódos Getter e Setters
  • Funções de string