Tela de Login com Bootstrap e CodeIgniter
UPDATE!
Estão ocorrendo 2 erros que muitos têm me perguntado a causa.
O primeiro é este:
A PHP Error was encountered Severity: Notice Message: Only variable references should be returned by reference Filename: core/Common.php Line Number: 257
Este é um bug nesta versão do CodeIgniter, 2.2.0. É um erro no retorno do valor de uma variável por referência. A solução é atualizar o CI para a versão 3.+ ou então abrir o código core/Common.php na linha 257 e fazer a seguinte mudança:
De: return $_config[0] =& $config; Para: $_config[0] =& $config; return $config[0];
A solução ideal é atualizar o CI.
O outro erro é em relação a uma mensagem na tela inicial dizendo que a variável $erro não existe. Eu tenho o costume de trabalhar com a opção short_open_tag habilitada no PHP, o que significa que basta eu digitar isso: <? ?> em vez disso: <?php ?> pra fazer tudo funcionar. Porém, a opção short_open_tag deve ser habilitada no PHP. Veja isso no php.ini, ou no WAMP, clique no ícone na bandeja, vá em PHP -> PHP Settings e habilite ao opção short_open_tag, então após reiniciar os servidor, seu código irá funcionar.
———————-
Olá.
No post de hoje vamos aprender a como integrar aquela tela de login que existe no exemplo no site do Bootrap no CodeIgniter, fazendo um sistema simples de autenticação.
Como a intenção aqui é apenas mostrar como podemos fazer um sistema de login bem interessante no CodeIgniter e também mostrar como utilizar aquela bela tela de login do Bootstrap, não iremos utilizar Banco de Dados.
O usuário/senha serão hardcode e também após o usuário conseguir logar-se, será apresentado apenas uma página com um texto informando o sucesso do login.
Para começar, vamos utilizar de uma funcionalidade que a Orientação à Objetos nos fornece para que possamos criar este projeto.
Vamos lançar mão da herança na orientação à objetos, onde nós conseguimos herdar as propriedades, métodos, etc da classe pai.
Para ser mais específico, o que nós vamos fazer pedir ao CodeIgniter para que todos os controllers que iremos proteger, estendam o controller chamado MY_Controller, que é onde iremos colocar o código de verificação de login do usuário.
Dentro do controller MY_Controller, na função __construct(), que é chamada sempre que uma classe é construída, nós vamos consultar uma variável na sessão para saber se o usuário passou pela tela de login.
Caso o valor desta variável seja igual a 1, então nada é feito e o fluxo continua, porém, caso o valor seja diferente de 1, indica então que o usuário não está logado, e assim nós redirecionamos ele novamente para a tela de login.
O legal aqui é que nós não vamos precisar especificar a tela de login quando precisarmos redirecionar o usuário.
Nós vamos simplesmente redirecioná-lo para a url base do sistema, pois como o CodeIgniter está configurado, neste caso, para que ele chame o controller home automaticamente que é o controller principal, e como este controller estende o MY_Controller, então, por mais que nós chamemos a URL base, se o usuário não estiver logado, ele vai ser redirecionado para a tela de login.
Se você se perdeu no texto acima, não se preocupe, logo mais você entenderá.
Vamos então começar a construir nosso sistema de login.
O primeiro passo é configurarmos o CodeIgniter para carregar automaticamente a biblioteca session e o helper url
Para isto, abra o arquivo application/config/autoload.php e na linha 55, que onde você informa quais bibliotecas deseja carregar, digite dentro da array a string session ficando assim:
$autoload['libraries'] = array('session');
Na linha, 67, deixe assim:
$autoload['helper'] = array('url');
O helper url nos traz função relacionadas à url do sistema.
Feito isso, agora você precisa configurar uma chave secreta para que a biblioteca session seja utilizada. Para isto abra o arquivo config.php que também está neste mesmo diretório.
Desça até a linha 227 e configure uma chave de criptografia. Veja meu exemplo abaixo:
$config['encryption_key'] = 'Aqui vai uma chave bem difícil de encriptação.';
Você pode colocar qualquer texto aí.
Agora vamos informar ao CodeIgniter para carregar como padrão nosso controller home. Para isto, abra o aquivo routes.php também dentro desta mesma pasta, e vá até o final do arquivo.
A linha 41 informa ao CodeIgniter que o controller padrão que será carregado, caso nenhum seja informado, é o welcome. Mude para home que será agora o controller principal.
Muito bem, feito isso, vamos agora criar o controller que será o responsável pela verificação do login do usuário.
Vamos criar um controller chamado MY_Controller e colocá-lo dentro da pasta application/core/ com o seguinte conteúdo:
<?php class MY_Controller extends CI_Controller { public function __construct() { parent::__construct(); $logado = $this->session->userdata("logado"); if ($logado != 1) redirect(base_url('index.php/login')); } }
O caminho para este controller ficará assim: application/core/MY_Controller.php
Agora, dentro da pasta application/controllers modifique o controller welcome.php para home.php lembrando de alterar também o nome da classe dentro deste arquivo, alterando de Welcome para Home e mude também a classe pai, que originalmente está como CI_Controller para MY_Controller.
Aqui que está o pulo do gato.
Todo controller que você quiser proteger, terá que estender o controller MY_Controller, pois é dentro deste que está o código de verificação do login do usuário.
Abaixo veja como ficou o código do controller home.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Home extends MY_Controller { public function index() { $this->load->view('v_home'); } }
Este controller basicamente só chama a view v_home, que traz a mensagem de sucesso quando o usuário estiver logado.
Vamos criar agora outro controller dentro desta pasta, chamado login.php. Este controller será responsável pelas funções relacionadas ao login do usuario.
Ele terá 3 funções dentro.
A primeira função index() simplesmente carrega a view login. Veja abaixo:
public function index() { $this->load->view('v_login'); }
A função logar() é para onde o action do formulário de login deverá apontar. Aqui nós fazemos a comparação do usuário/senha digitados com os gravados.
Neste exemplo o usuário/senha estão hardcode. Mas você fará a modificação para um banco de dados, caso necessite.
Veja abaixo o código:
public function logar(){ $usuario = $this->input->post("usuario"); $senha = sha1($this->input->post("senha")); //Código sha1 da senha 123456 7c4a8d09ca3762af61e59520943dc26494f8941b //O usuário no exemplo aqui será usuario@email.com.br //Mas em um projeto real, você trará isto do banco de dados. //Se o usuário e senha combinarem, então basta eu redirecionar para a url base, pois agora o usuário irá passa //pela verificação que checa se ele está logado. if ($usuario == "usuario@email.com.br" && $senha == '7c4a8d09ca3762af61e59520943dc26494f8941b' ) { $this->session->set_userdata("logado", 1); redirect(base_url()); } else { //caso a senha/usuário estejam incorretos, então mando o usuário novamente para a tela de login com uma mensagem de erro. $dados['erro'] = "Usuário/Senha incorretos"; $this->load->view("v_login", $dados); } }
E a última função é a logout() onde eu simplesmente destruo a variável logado que é responsável por indicar se o usuário está ou não logado no sistema. Veja:
/* * Aqui eu destruo a variável logado na sessão e redireciono para a url base. Como esta variável não existe mais, o usuário * será direcionado novamente para a tela de login. */ public function logout(){ $this->session->unset_userdata("logado"); redirect(base_url()); }
Atenção!
Algo muito importante. O controller login.php não pode estender a classe MY_Controller, pois não há sentido em queremos proteger a tela de login.
Caso você estenda a classe MY_Controller, o navegador irá entrar em loop.
Este controller deve estender normalmente o controller CI_Controller do CodeIgniter.
Veja abaixo o código completo do controller login.php:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed'); class Login extends CI_Controller { public function index() { $this->load->view('v_login'); } public function logar(){ $usuario = $this->input->post("usuario"); $senha = sha1($this->input->post("senha")); //Código sha1 da senha 123456 7c4a8d09ca3762af61e59520943dc26494f8941b //O usuário no exemplo aqui será usuario@email.com.br //Mas em um projeto real, você trará isto do banco de dados. //Se o usuário e senha combinarem, então basta eu redirecionar para a url base, pois agora o usuário irá passa //pela verificação que checa se ele está logado. if ($usuario == "usuario@email.com.br" && $senha == '7c4a8d09ca3762af61e59520943dc26494f8941b' ) { $this->session->set_userdata("logado", 1); redirect(base_url()); } else { //caso a senha/usuário estejam incorretos, então mando o usuário novamente para a tela de login com uma mensagem de erro. $dados['erro'] = "Usuário/Senha incorretos"; $this->load->view("v_login", $dados); } } /* * Aqui eu destruo a variável logado na sessão e redireciono para a url base. Como esta variável não existe mais, o usuário * será direcionado novamente para a tela de login. */ public function logout(){ $this->session->unset_userdata("logado"); redirect(base_url()); } }
A parte de controllers termina aqui. Agora vamos criar as viewes login e home.
A view login é a tela de login que vamos utilizar lá do Bootstrap.
Originalmente o exemplo do bootstrap tem uma checkbox para relembrar o login. Como esta é uma etapa um pouco mais complexa, não vou abordar aqui, por isso removi este input do formulário.
Veja abaixo como ficou o código completo da view v_login.php:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="../../favicon.ico"> <title>Template de Login do Bootstrap</title> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> <!-- Custom styles for this template --> <link href="<?= base_url('includes/signin.css') ?>" rel="stylesheet"> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <div class="container"> <form class="form-signin" role="form" method="post" action="<?= base_url('index.php/login/logar') ?>"> <h2 class="form-signin-heading">Por favor, logue-se</h2> <input type="email" class="form-control" placeholder="Email address" required autofocus name="usuario"> <input type="password" class="form-control" placeholder="Password" required name="senha"> <button class="btn btn-lg btn-primary btn-block" type="submit">Fazer login</button> <? if (isset($erro)): ?> <div class="alert alert-danger" role="alert" style="margin-top: 10px;"><?= $erro; ?></div> <? endif; ?> </form> </div> <!-- /container --> </body> </html>
A outra view é a v_home.php. Esta seria a view principal do seu sistema que é protegido.
O usuário só vai conseguir ver esta view, se conseguir passar com sucesso pela tela de login.
Aqui eu só coloquei uma mensagem de sucesso e um link para o usuário deslogar. Veja:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <meta name="author" content=""> <link rel="icon" href="../../favicon.ico"> <title>Template de Login do Bootstrap</title> <!-- Latest compiled and minified CSS --> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css"> <!-- Custom styles for this template --> <link href="<?= base_url('includes/signin.css') ?>" rel="stylesheet"> <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries --> <!--[if lt IE 9]> <script src="https://oss.maxcdn.com/html5shiv/3.7.2/html5shiv.min.js"></script> <script src="https://oss.maxcdn.com/respond/1.4.2/respond.min.js"></script> <![endif]--> </head> <body> <div class="container"> <h1 class="text-center">Parabéns, você está logado.</h1> <p>Lembre-se, para proteger seus controllers, basta estender o controller MY_Controller, e assim, automaticamente seus controllers passarão pela verificação de senha. </p> Cliqui aqui para deslogar: <a href="<?= base_url('index.php/login/logout') ?>">Deslogar</a></p> </div> </body> </html>
Bom, é isto. O sistema de login termina aqui.
Abaixo segue este sistema funcionando para você testar. Os dados de acesso são:
Usuário: usuario@email.com.br
Senha: 123456
Para você baixar o código fonte completo do exemplo, clique no link abaixo:
Baixar o Código Fonte do Exemplo
Um grande abraço e até o próximo post.
Fábio.