Você está na página 1de 17

Funcionamento do sistema de autenticao em PHP Descrio das distintas pginas que formam o sistema de autenticao e seu funcionamento, baseado

em usurio e senha. Um sistema de autenticao um mdulo de segurana para nos assegurar de que o usurio que visita as pginas quem diz ser. Obviamente, sabendo que esse usurio conhecido, poderemos lhe dar acesso a mais aspectos da pgina que se fosse um usurio desconhecido. Porm suponho que, se estiver lendo este artigo, j conhecer o que um sistema de autenticao e o que deseja fazer criar um para suas pginas. Referncia: Este manual requer o conhecimento bsico de PHP que, no caso de no t-lo, se pode aprender em nosso Manual de Programao em PHP. Esquema de um sistema de autenticao Vamos comear definindo um diagrama para realizar a autenticao de usurio numas pginas web, que nos servir para programar logo as pginas ajustando-se ao diagrama.

Na imagem anterior podemos ver o diagrama, que comea pela pgina onde se pede um usurio e senha para acessar aplicao de acesso restringido. Os dados de autenticao (usurio e senha escritos na pgina inicial) se enviam pgina desenhada com linha de pontos, que se encarrega de fazer uma comprovao de tais dados do usurio. Segundo os dados de autenticao, se redireciona ao navegador pgina da aplicao restringida, no caso de que no sejam corretos, ou pgina onde se volta a escrever o usurio/senha, no caso de que sejam incorretos. Esta pgina foi desenhada com linha de pontos porque no uma pgina onde o navegador para, e sim que somente uma pgina de passagem que redireciona a um site ou outro dependendo dos dados que receba. A aplicao de acesso restringido, a parte de mostrar as funcionalidades que queramos proteger com usurio e senha, deve de realizar umas comprovaes de segurana para saber se o processo de autenticao se passou com xito ou se est tentando acessar de maneira no permitida a essa pgina. Esta comprovao foi desenhada como uma camada com cor verde mais escura sobre a pgina da aplicao. Se no se satisfaz tal comprovao (o usurio no se autenticou corretamente) se volta pgina onde se deve

escrever o usurio e a senha. Este o esquema bsico, que espero que se entenda bem. Agora, vejamos algumas perguntas que o leitor poderia fazer. Por que fazemos esta comprovao de segurana dentro da aplicao? Poderia ser que algum conhecesse a URL da aplicao de acesso restringido e a escrevesse diretamente sobre a barra de endereos do explorador, portanto fazemos esta comprovao para saber que realmente no se est acessando sem passar pela pgina que comprova se o usurio/senha correto. Como sabemos que certamente se passou pela pgina que comprova os dados de autenticao? Esta comprovao se poderia fazer de vrias maneiras. Sendo assim, depende de nosso script de autenticao e o nvel de segurana que tratemos de implementar. Um exemplo simples poderia ser criar uma varivel de sesso na pgina que comprova os dados, se que eram corretos, e com uma camada de segurana das pginas de acesso restringido comprovaramos se essa sesso est ou no definida. No caso de desejar burlar a segurana, como poderia um usurio entrar na pgina da aplicao se no h links diretos e para passar a ela necessitamos que nos redirecione a pgina de comprobao do usurio/senha? Pois de diversas maneiras, para comear, o histrico dos computadores salva as URL s que se acessou e qualquer pessoa poderia recuperar a URL de nossa aplicao com acesso restringido. Tambm se poderia provar diferentes URL que poderamos imaginar como possveis para a aplicao e esperar a acertar com o nome de arquivo em algum momento, inclusive esta tarefa poderia ser encomendada a um programa para realizar muitas mais provas. De qualquer forma, nossa segurana no pode ficar em simplesmente que os possveis intrusos no conheam o endereo da pgina.

Pgina inicial com o formulrio de autenticao em PHP


Pgina que mostra o formulrio onde o visitante deve introduzir seu nome de usurio e senha, necessrios para acessar aplicao segura.

Vamos realizar a pgina inicial, que tem o formulrio de autenticao no qual o visitante deveria preencher com seu usurio e senha. Como a pgina inicial, a chamaremos index.php, que o documento padro configurado em nosso servidor. Para realizar esta pgina, utilizaremos HTML bsico, exceto em uma comprovao que nos permitir saber se se acessa ao formulrio de novo por no ter introduzido corretamente o usurio e senha, pois, nesse caso, teria que mostrar um aviso informando que o usurio ou a senha no so vlidos. Para passar pgina inicial a mensagem de que o usurio/senha introduzidos no so vlidos, utilizaremos uma varivel passada atravs da URL. Ser chamada de errousuario, e se contiver a cadeia "sim" que estamos recebendo um erro. O cdigo seria o seguinte:

<html> <head> <title>Autentificao PHP</title> </head> <body> <h1>Autentificao PHP</h1> <form action="control. php" method="POST"> <table align="center" width="225" cellspacing="2" cellpadding="2" border="0"> <tr> <td colspan="2" align="center" <?if ($_GET["errousuario"]=="si"){?> bgcolor=red><span style="color:ffffff"><b>Dados incorretos</b></span> <?}else{?> bgcolor=#cccccc>Introduza sua senha de acesso <?}?></td> </tr> <tr> <td align="right">USER:</td> <td><input type="Text" name="usuario" size="8" maxlength="50"></td> </tr> <tr> <td align="right">PASSWD:</td> <td><input type="password" name="senha" size="8" maxlength="50"></td> </tr> <tr> <td colspan="2" align="center"><input type="Submit" value="ENTRAR"></td> </tr> </table> </form> </body> </html> Nota: A varivel errousuario, recebida pela URL e que informa se se produziu um erro anterior ao introduzir usurio e senha, se est percorrendo pela mediao do array associativo $_GET, que salva todas as variveis enviadas pela URL.

O formulrio tem o atributo action dirigido para a pgina "control.php", que a que se encarrega de percorrer os dados e ver se so corretos. Ser tratada no prximo captulo.

Controle dos dados de autenticao em PHP


Aqui veremos se os dados de autenticao so corretos e dependendo de se so ou no, se redirecionar ao navegador aplicao segura ou ao formulrio inicial, respectivamente.

Esta pgina ser encarregada de decidir se os dados de configurao so corretos e agir em conseqncia. Dependendo do nvel de segurana que quisermos aplicar a nossa aplicao, esta pgina ser mais ou menos complicada. princpio no desejo confundir muito as coisas, portanto explicarei uma verso muito reduzida deste arquivo de controle, na que se comprova se o usurio e senha so dois valores especficos. Isto tem a desvantagem que s podemos criar um usurio/senha diferente e no um sistema que permita muitos usurios distintos. Bom, na verdade sim que permitir que acessem muitos usurios de uma s vez, porm utilizando todos o mesmo nome de usurio e senha. Em aplicaes mais avanadas poderamos ter em um banco de dados uma lista de usurios com suas senhas. Ento, neste arquivo de controle deveramos fazer uma busca para ver se existe uma correspondncia no banco de dados desse usurio com essa senha. Veremos isto mais adiante, agora ficaremos com a verso

reduzida. Depois da comprovao podero ocorrer duas coisas: Se os dados so corretos, definir uma varivel de sesso que servir para saber que esse visitante foi validado corretamente e tem permisso para acessar aplicao. Ademais, redirecionar ao visitante pgina da aplicao restringida. Se o usurio/senha no era correto, se envia ao navegador pgina de incio passando a varivel errousuario=sim, que indica que houve um erro na autenticao. O cdigo pode ser visto a seguir:
<? //vemos se o usurio e senha so vlidos if ($_POST["usuario"]=="miguel" && $_POST["senha"]=="qwerty"){ //usuario e senha vlidos //defino uma sesso e salvo dados session_start(); $_SESSION["autenticado"]= "SI"; header ("Location: aplicacao.php"); }else { //se no existir lhe mando outra vez ao portal header("Location: index.php?errousuario=sim"); } ?>

Camada de segurana em PHP


Este captulo explicar o funcionamento do mdulo de segurana.

Este arquivo, em nosso caso chamado seguranca.php, se encarregar de dotar segurana a toda a aplicao de acesso restringido. A tcnica que vamos utilizar inclu-lo ao princpio de todas as pginas que quisermos que permitam um acesso restringido. O mdulo de segurana, includo ao princpio de cada arquivo, realizar as comprovaes oportunas e atuar permitindo ver o arquivo ou denegando sua visualizao dependendo de tais comprovaes. Dependendo do nvel de segurana que desejarmos implementar, a criao deste arquivo pode ser mais ou menos complicada. Como no desejo complicar em um princpio os scripts, esta verso resultar bastante simples. O nico que farei ser recuperar a varivel de sesso onde salvo se esse usurio tiver sido autenticado ou no. Logo, se comprova essa varivel para saber se se autenticou o usurio ou no, realizando estas aes: Se no tiver sido autenticado, redireciono ao navegador pgina que tem o formulrio de autenticao. Ademais, saio do script PHP, com o que a pgina deixa de se executar e o resto no se ver. S se mandar ao navegador o redirecionamento com o que o navegador se mover ao formulrio e ser impossvel ver nada na pgina segura. Se tiver autenticado, no fao nada. Nem sequer trato este caso, de modo que continuaria se executando a pgina com o contedo que correspondesse. No h que esquecer que este arquivo de segurana se executar como um include ao princpio de todos os arquivos da aplicao restringida, o que significa que, se no se faz nada, se continuaria mostrando a pgina onde este arquivo est includo.

O cdigo se pode ver a seguir:


<? //Inicio a sesso sessao_start(); //COMPROVA QUE O USUARIO ESTA AUTENTICADO if ($_SESSAO["autenticado"] != "SI") { //se no existe, envio pgina de autenticao header("Location: index. php"); //ademais saio deste script exit(); } ?>

Arquivos da aplicao com acesso restringido em PHP


Mostraremos um exemplo do cdigo de uma das pginas web que formaria a aplicao segura.

A aplicao com acesso restringido se realizar como qualquer outra aplicao de PHP, com a exceo de que, a todos os arquivos que quisermos proteger, tero que ser includos ao princpio a camada de segurana, representada pelo arquivo seguranca.php. Como dizia, tudo no arquivo da aplicao se realizar como qualquer outro arquivo de PHP, ou seja, somente com incluir o mdulo de segurana, o arquivo j ter o acesso restringido e todo o demais o faremos de maneira transparente a este estado de segurana. O cdigo de uma pgina segura seria o seguinte:
<?include ("seguranca.php");?> <html> <head> <title>Aplicao segura</title> </head> <body> <h1>Se estiver aqui porque se autenticou</h1> <br> ---<br> Aplicao segura <br> ---<br> <br> <a href="sair.php">Sair</a> </body> </html> Importante: O include do arquivo seguranca.php h que realiz-lo na primeira linha do arquivo PHP da aplicao. Se no o fizermos na primeira linha ou se escrevermos texto na pgina antes de incluir a camada de segurana, o script poderia falhar e fazer com que no funcione a aplicao ou que seja menos segura. Este efeito se produz porque no se pode escrever na pgina nada se se deseja fazer um redirecionamento com PHP (funo header) e se se escreve algo, o redirecionamento no poder funcionar.

Um detalhe que inclumos um link para sair da aplicao, que se dirige ao arquivo

sair.php. Explicaremos o sentido desta ao e o script de sair.php no seguinte captulo.

Sair da aplicao segura em PHP


Neste captulo veremos com um simples exemplo como sair da aplicao de acesso restringido.

A segurana da aplicao se baseia na definio de umas variveis de sesso que se consultam em cada pgina segura. Pode ocorrer que o usurio entre na aplicao e inicie uma sesso e que v embora da aplicao segura sem fechar a sesso, com o qual ficaria aberta para que qualquer outra pessoa pudesse acessar a aplicao voltando pelo histrico de pginas do navegador. As sesses se finalizam sozinhas quando passa um determinado tempo sem receber novas peties, porm no desejamos que antes que se finalize se possa acessar com esse computador a nossa aplicao restringida. Parece interessante, ento, oferecer ao visitante a opo de acabar a sesso em qualquer momento, para nos asseguramos nesse caso que a sesso terminou e no se poder acessar se no for introduzindo novamente o usurio e a senha corretos. O arquivo em concreto o nico que faz terminar a sesso associada a seu acesso. Podemos ver o cdigo a seguir.
<? session_start(); session_destroy(); ?> <html> <head> <title>Saiu!!</title> </head> <body> Obrigado pelo seu acesso <br> <br> <a href="index.php">Formulrio de autentificao</a> </body> </html>

Diferentes formas de fechar sesso em PHP


Como fechar uma sesso autenticada corretamente, por inatividade ou por fechamento do navegador por parte do usurio.

Veremos como fechar a sesso do usurio quando: O tempo de inatividade do usurio supere "x" quantidade de tempo (segundos, minutos, etc...). O usurio feche o navegador e abandone por completo nosso site.

Fechamento de sesso por inatividade em PHP: mdulo de controle de dados

Algo que pode parecer muito bvio para uns e muito complexo para outros, mas que inegavelmente muitos de ns j nos perguntamos em algum momento: Como expirar uma sesso em PHP? Agora veremos que simples . S temos que: Criar uma nova sesso que salve uma data e hora Comprovar em nossa camada de segurana o tempo transcorrido entre a sesso salva e a hora atual Atualizar a sesso ou destru-la segundo corresponda

O primeiro que devemos fazer ento, criar a nova seo e atribuir-lhe como valor, a hora atual. Faremos isto no momento que o usurio entra no sistema com seus dados de acesso.
<? //vemos se o usurio e senha so vlidos if ($_POST["usuario"]=="miguel" && $_POST["senha"]=="qwerty"){ //usuario e senha vlidos session_name("loginUsuario"); //atribui um nome sesso para poder salvar diferentes dados session_start(); // inicio l sesso $_SESSION["autenticado"]= "SI"; //defino a sesso que demonstra que o usurio est autorizado $_SESSION["ultimoAcesso"]= date("Y-n-j H:i:s"); //defino a data e hora de inicio de sesso em formato aaaa-mm-dd hh:mm:ss header ("Location: aplicacao.php"); }else { //se no existe lhe mando outra vez ao portal header("Location: index.php?errousuario=si"); } ?>

Fechamento de sesso por inatividade em PHP: mdulo de segurana O segundo passo, ser comprovar o tempo transcorrido entre a data salva e a hora atual em nossa camada de segurana e atuar em conseqncia. Para faz-lo, teremos que realizar um clculo muito simples: tempo transcorrido = (hora atual - data salva) E logo, restar saber se o tempo transcorrido maior, menor ou igual que o tempo de expirao da sesso (representado como "x"): se (tempo transcorrido >= x), atuo em conseqncia ao achado Para efetuar estes clculos utilizaremos como unidade de tempo o segundo. Em nosso exemplo, expiraremos a sesso, transcorridos 10 minutos de inatividade (onde: 10*60 = 600 segundos). Para efetuar estes clculos e tomar como unidade de medida o segundo, ser necessrio converter as datas a segundos. Para isso, utilizaremos a funo strtotime. Portanto, calcularemos o tempo transcorrido (tempo transcorrido = (hora atual data salva)) da seguinte maneira:
<? //iniciamos a sesso session_name("loginUsuario");

session_start(); //antes de fazer os clculos, comprovo que o usurio est logado //utilizamos o mesmo script que antes if ($_SESSION["autenticado"] != "SI") { //se no est logado o envio pgina de autenticao header("Location: index.php"); } else { //seno, calculamos o tempo transcorrido $dataSalva = $_SESSION["ultimoAcesso"]; $agora = date("Y-n-j H:i:s"); $tempo_transcorrido = (strtotime($agora)-strtotime($dataSalva)); //comparamos o tempo transcorrido if($tempo_transcorrido >= 600) { //se passaram 10 minutos ou mais session_destroy(); // destruo a sesso header("Location: index.php"); //envio ao usurio pgina de autenticao //seno, atualizo a data da sesso }else { $_SESSION["ultimoAcesso"] = $agora; } } ?>

Fechamento de sesso ao fechar o navegador em PHP


Cdigo em PHP para fechar sesses quando se fecha o navegador.

Introduo Muito mais simples do que se imagina, fazer com quem uma sesso expire de forma automtica quando o usurio fechar o navegador. principio, vamos definir a que nos referimos com fechar o navegador. O servidor entender que o usurio fechou o navegador quando j no se encontre visitando nenhuma das pginas de nosso site. Ou seja, se um usurio que para navegar nosso site abriu pelo menos 2 pginas em 2 janelas diferentes, o servidor considerar que fechou o navegador quando at a ltima janela for abandonada. Seja porque o usurio a fechou ou fora para outro site que no o nosso. Ento, para que a sesso expire ao fechar o navegador, ter que por um lado, forar ao php.ini a que propague a sesso somente em cookies e por outro lado, lhe atribuir a esta, uma durao zero. Para forar ao php.ini h duas formas: modificar o php.ini diretamente ou mudar os valores desde nosso script. Opo 1 Configurar o arquivo de incio de php (php.ini) em forma direta. Se tiver acesso a este arquivo, ter que buscar e mudar o valor a:
session.use_trans_sid = 0 session.use_only_cookies = 1

Esta ltima, justamente ser a que indicar que a sesso deve se propagar s atravs de cookies.

Opo 2 Mudar a configurao do php.ini atravs de nosso script php. Esta opo consiste em forar ao php.ini atravs de nosso script php (Nem todos os servidores tm habilitada esta opo. Se o servidor no for prprio, por via das dvidas, consulte com seu provedor). Para faz-lo, utilizaremos a funo ini_set()
ini_set("session.use_trans_sid","0"); ini_set("session.use_only_cookies","1");

Agora s restar, mudar o parmetro de durao cookie da sesso. Faremos isto em nosso script com a seguinte instruo: session_set_cookie_params(0, "/", $HTTP_SERVER_VARS["HTTP_HOST"], 0); Com o qual estaremos indicando uma durao e 0 (zero) segundos. Isto significar que durar at que termine o script. Por fim, chegamos ao cdigo: Fechamento de sesso ao fechar o navegador em PHP: mdulo de controle de dados Voc ver refletidas as mudanas ao script anterior, indicadas em negritos. Estas mudanas sero tambm as que se apliquem ao mdulo de segurana. De qualquer forma, exponho aqui os dois cdigos.
<? //se for necessrio mudar a config. Do php.ini atravs de seu script ini_set("session.use_only_cookies","1"); ini_set("session.use_trans_sid","0"); //vemos se o usurio e senha so vlidos if ($_POST["usuario"]=="miguel" && $_POST["senha"]=="qwerty"){ //usurio e senha vlidos session_name("loginUsuario"); //atribuo um nome sesso para poder salvar diferentes dados session_start(); // inicio a sesso session_set_cookie_params(0, "/", $HTTP_SERVER_VARS["HTTP_HOST"], 0); //mudamos a durao cookie da sesso $_SESSION["autenticado"]= "SI"; //defino a sesso que demonstra que o usurio est autorizado $_SESSION["ultimoAcesso"]= date("Y-n-j H:i:s"); //defino a data e a hora de incio de sesso em formato aaaa-mm-dd hh:mm:ss header ("Location: aplicacao.php"); }else { //se no existe lhe mando outra vez ao portal header("Location: index.php?errousuario=si"); } ?>

Fechamento de sesso ao fechar o navegador em PHP: mdulo de controle de dados Voc ver refletidas as mudanas ao script anterior, indicados em negritos.
<? //se for necessrio mudar a config. do php.ini atravs de seu script ini_set("session.use_only_cookies","1"); ini_set("session.use_trans_sid","0");

//iniciamos a sesso session_name("loginUsuario"); session_start(); session_set_cookie_params(0, "/", $HTTP_SERVER_VARS["HTTP_HOST"], 0); //mudamos a durao cookie da sesso //antes de fazer os clculos, comprovo que o usurio est logado //utilizamos o mesmo script que antes if ($_SESSION["autenticado"] != "SI") { //se no estiver logado o envio pgina de autenticao header("Location: index.php"); } else { //seno, calculamos o tempo transcorrido $dataSalva = $_SESSION["ultimoAcesso"]; $agora = date("Y-n-j H:i:s"); $tempo_transcorrido = (strtotime($agora)-strtotime($dataSalva)); //comparamos o tempo transcorrido if($tempo_transcorrido >= 600) { //se passaram 10 minutos ou mais session_destroy(); // destruo a sesso header("Location: index.php"); //envio o usurio pag. de autenticao //seno, atualizo a data da sesso }else { $_SESSION["ultimoAcesso"] = $agora; } } ?>

Autenticao PHP para mltiplos usurios usando MySQL


Pgina PHP que necessitaramos para realizar um acesso restringido por chave e senha para mltiplos usurios, onde cada um tenha seus dados de acesso prprios, que se salvam no banco de dados.

Veremos as pginas PHP que necessitaramos para realizar um acesso restringido por chave e senha para mltiplos usurios, onde cada um tenha uns dados de acesso prprios.
Nota: Este artigo vem a complementar o manual Sistema de Autenticao em PHP. De fato, neste artigo s vamos tratar a pgina que percorre os dados do usurio (seu nome e senha) e comprova se so corretos, redirecionando aplicao segura (se os dados se correspondem com algum usurio do banco de dados), ou pgina de entrada (se os dados no correspondem com nenhum usurio registrado).

O primeiro lembrar o esquema de pginas do sistema de autenticao proposto. O podemos ver no artigo Funcionamento do sistema de autenticao em PHP. Ns vamos tratar de colocar aqui um cdigo para a pgina "comprovo dados" O banco de dados O banco de dados que vamos utilizar conter uma tabela para os usurios, onde cada um ir dispor, pelo menos, de dois campos: um nome de usurio e uma senha, os dois de tipo texto. Tabela usurio
Nome do campo Tipo do campo

nome_usuario Texto

chave_usuario Texto Em um banco de dados de usurios, o nome de usurio deveria ser um valor nico, que no se repita para outro usurio, ou seja, no poderemos ter dois usurios com o mesmo nome. Por esta razo, o campo nome_usuario poderia ser a chave principal da tabela, embora tambm poderamos ter criado um campo adicional, chamado por exemplo id_usuario, de tipo autonumrico e coloc-lo como chave principal. Para conseguir no inserir dois usurios com o mesmo nome de usurio, na hora de inseri-los na tabela, comprovaremos que no tenha nenhum usurio j introduzido com o nome de usurio que se pretende inserir. Este passo, embora seja importante, no o veremos, pois s nos centraremos em decidir se um usurio pode entrar ou no na aplicao, supondo que os usurios se encontram j inseridos no banco de dados. No exemplo, supomos que utilizamos um banco de dados MySQL, entretanto, qualquer tipo de banco de dados poder servir para uns objetivos como os que nos propomos. O funcionamento do script O script que se utilizar para decidir se um usurio pode ou no entrar na aplicao muito simples. Simplesmente faz uma chamada ao banco de dados para comprovar se os dados de autenticao escritos pelo visitante (usurio e senha) correspondem com os de algum usurio. No caso de ser assim, se permite a entrada e de no ser assim, se denega.
Nota: Este script foi comentado em uma verso simplificada no artigo Controle dos dados de autenticao em PHP, englobado dentro do manual Sistema de autenticao PHP

O primeiro seria abrir uma conexo com o banco de dados e selecionar o banco com o qual vamos trabalhar.
//conecto com o banco de dados $conn = mysql_connect(" servidor","usuario","password"); //seleciono o BD mysql_select_db("nome_bd",$conn);

Um segundo passo construir uma instruo SQL que nos permita comprovar se existe ou no um usurio com os dados de autenticao introduzidos. Utilizamos uma simples instruo SELECT, sobre a tabela de usurios, onde se extraem usurios que tenham o mesmo nome de usurio e a senha introduzidos na pgina de acesso.
//Instrucao SQL para buscar um usuario com esses dados $ssql = "SELECT * FROM usuario WHERE nome_usuario='$usuario' and chave_usuario='$senha'"; //Executo a instrucao $rs = mysql_query($ssql,$conn);

Se essa instruo SELECT responde com algum registro encontrado, saberemos que existe um usurio onde seus dados de autenticao correspondem perfeitamente com os introduzidos. Nesse caso poderemos realizar as aes encaminhadas a permitir o acesso. Caso contrrio, se a instruo SELECT no encontrar nenhum registro, saberemos que no existe um usurio com os dados de autenticao introduzidos e portanto, deveremos realizar as aes encaminhadas a restringir o acesso.

if (mysql_num_rows($rs)!=0){ //usuario e senha vlidos //defino uma sesso e salvo dados session_start(); session_register("autenticado"); $autenticado = "SI"; header ("Location: aplicacao.php"); }else { //se nao existe lhe mando outra vez ao portal header("Location: index.php?errousuario=sim"); }

As aes para restringir ou permitir o acesso so exatamente iguais as que vnhamos utilizando no script de controle sem utilizar o banco de dados. Portanto, no vamos coment-las mais, e sim lhes referimos ao artigo onde as explicamos. O cdigo completo do exemplo seria o seguinte.
<? //conecto com o banco de dados $conn = mysql_connect("servidor","usuario","password"); //seleciono o BD mysql_select_db("nome_bd",$conn); //Instrucao SQL para buscar um usuario com esses dados $ssql = "SELECT * FROM usuario WHERE nome_usuario='$usuario' and chave_usuario='$senha'"; //Executo a instrucao $rs = mysql_query($ssql,$conn); //vemos se o usuario e senha so validos //se a execucao da instrucao SQL nos da algum resultado //eh que sim que existe essa conbinacao usuario/senha if (mysql_num_rows($rs)!=0){ //usuario e senha validos //defino uma sessao e salvo dados session_start(); session_register("autenticado"); $autenticado = "SI"; header ("Location: aplicacao.php"); }else { //se nao existe lhe mando outra vez ao portal header("Location: index.php?errousuario=si"); } mysql_free_result($rs); mysql_close($conn); ?> Nota: importante destacar que esta pgina no deveria conter nenhum tipo de texto antes da abertura de cdigo PHP, nem sequer quebras de linha. Isto devido a que ao final se realiza um redirecionamento e este tipo de instrues somente se pode executar se no se escreveu ainda nenhum caractere no corpo. Para ser mais especficos, este o erro que obtemos se escrevemos antes na pgina de enviar os cabealhos: Warning: Cannot add header information - headers already sent by (output started at /htdocs/exemplos/autentic-php_bd/controle.php

Autenticar usurio e salvar uma cookie com PHP


Sistema de autenticao de usurios em PHP, onde se oferece a opo de memorizar seu usurio no computador e salvar uma cookie para lembrar o usurio e no ter que voltar a se autenticar.

Vamos criar um sistema para autenticar usurios com PHP, com a particularidade que este sistema vai a oferecer ao visitante a opo de salvar seu usurio, para que a pgina o lembre em sucessivos acessos e no tenha que voltar a se autenticar. O usurio ser salvo em uma cookie para que o navegador possa lembr-lo em suas distintas visitas. Esta uma opo muito til para que o visitante no tenha que estar todo o tempo se autenticando, com seu usurio e senha, cada vez que acessa pgina web. Certamente uma opo que devemos ter visto em um monto de web sites. Este artigo uma continuao de uma srie de workshops e exemplos que vimos anteriormente no manual de Autenticao de usurios em PHP. Neste workshop no vamos realizar uma autenticao muito elaborada, e sim uma bem simples, para facilitar o desenvolvimento. Logo, a complexidade aportar a parte de salvar o usurio em uma cookie, que no difcil de fazer, porm sim requer de novos conhecimentos que aplicar. Explicao de armazenar o usurio em uma cookie Primeiro, vamos explicar com palavras o modelo de trabalho que vamos aplicar para armazenar o usurio em uma cookie. No investiguei como podero fazer isto outras pessoas em outros desenvolvimentos, porm acho que criei uma forma adequada para faz-lo. Digo isto porque o primeiro que pensei, foi colocar o nome de usurio e a senha em umas cookies. Seria simplesmente criar um par de cookies no sistema do usurio com essas duas variveis. Porm, logo pensando, no me parecia muito atraente a possibilidade de incluir essa informao sensvel em umas cookies no computador do usurio, pelo caso de haver alguma pessoa que pudesse l-las, copi-las e utiliz-las em outro computador. Talvez no deveria me preocupar com isso, porm de qualquer forma, no gostava da possibilidade de armazenar o nome de usurio e senha, e sim de armazenar outro tipo de informao menos crtica. Ento, o que pensei foi de armazenar o identificador do usurio. Mas claro, se algum conseguia criar uma cookie no sistema com qualquer identificador de usurio, poderia acessar a conta desse usurio. Portanto, tinha que aplicar outra estratgia adicional para assegurar que esse identificador de usurio no se possa reproduzir. Finalmente, decidi gerar um nmero aleatrio quando o usurio se conecta pgina e se autentica corretamente, e armazen-lo em dois sites, primeiro no registro do usurio no banco de dados e logo, na cookie. Sendo assim, quando o visitante decide que quer que o web site lembre sua conta de usurio, para no ter que voltar a se autenticar em seguintes acessos, se salvam duas coisas nas cookies do navegador: seu identificador de usurio e uma marca aleatria (tal marca tambm se armazena no banco de dados, associada ao seu usurio). Nos seguintes acessos, primeiro se comprova se existem essas cookies no navegador do visitante e se o conjunto de identificador de usurio e a marca aleatria armazenados na cookie coincidem com o que temos no banco de dados. Com outras palavras, salvaremos na cookie o identificador de usurio. Ademais, geramos um nmero aleatrio que salvamos em dois lugares: 1) na tabela de usurio, no registro correspondente ao usurio que deseja que se lembre a chave e 2) em uma cookie. Logo, quando os usurios se conectam de novo, no s se comprova que tenha a cookie com o identificador de usurio, como tambm que tenha a outra cookie com a marca aleatria e que seja a mesma que temos no

banco de dados para esse mesmo usurio. Espero que se possa entender o sistema. No obstante, espero clare-lo ainda mais medida que explique o cdigo PHP e o banco de dados que vamos utilizar. Tabela de usurio Na tabela de usurio que criamos para este exemplo temos 4 campos: Identificador de usurio Nome de usurio Chave de acesso Marca aleatria que se colocou na cookie

Para o exemplo, criamos uma tabela e inserimos dois usurios para fazer provas. Ter uma forma como esta:

Cdigo da pgina PHP Agora vou explicar por partes o cdigo PHP para autenticar ao usurio e salvar a informao de acesso na cookie, assim como a parte de comprovar se o usurio tinha a cookie com seu acesso salvo no computador. Primeiro, vamos comear mostrando o formulrio HTML:
<form action="prova-cookies.php" method="post"> Usuario: <input type="text" name="usuario"> <br> Chave: <input type="text" name="chave"> <br> <input type="checkbox" name="salvar_chave" value="1"> Memorizar o usurio neste computador <br> <input type="submit" value="Entrar"> </form>

Como vemos, tem os campos para escrever o nome de usurio e a chave e um campo checkbox adicional para que o usurio marque se quer que seu acesso se salve em seu computador. Agora vou mostrar o cdigo que utilizaramos para receber por post, do formulrio de autenticao, o nome de usurio e senha. Este cdigo tambm tem que detectar se o usurio queria que se salvasse seu acesso no computador.
//deveria comprovar se o usuario eh correto $ssql = "select * from usuario where usuario = '" . $_POST["usuario"] . "' and chave='" . $_POST["chave"] . "'"; //echo $ssql; $rs = mysql_query($ssql); if (mysql_num_rows($rs)==1){ //TODO CORRETO!! Detectei um usuario $usuario_encontrado = mysql_fetch_object($rs); //agora devo ver se o usuario queria memorizar sua conta neste computador if ($_POST["salvar_senha"]=="1"){ //pediu para memorizar o usuario //1) crio uma marca aleatoria no registro deste usuario

//alimentamos o gerador de aleatorios mt_srand (time()); //geramos um nmero aleatorio $numero_aleatorio = mt_rand(1000000,999999999); //2) coloca a marca aleatoria na tabela de usuario $ssql = "update usuario set cookie='$numero_aleatorio' where id_usuario=" . $usuario_encontrado>id_usuario; mysql_query($ssql); //3) agora coloco uma cookie no computador do usuario com o identificador do usuario e a cookie aleatoria setcookie("id_usuario_dw", $usuario_encontrado->id_usuario , time()+(60*60*24*365)); setcookie("marca_aleatoria_usuario_dw", $numero_aleatorio, time()+(60*60*24*365)); } echo "Autenticado corretamente"; //header ("Location: conteudos_protegidos_cookie.php"); }else{ echo "Falha de autenticao!"; echo "<p><a href='prova-cookies.php'>Voltar</a>"; }

Para comprovar se os dados de autenticao que recebemos pelo formulrio so corretos, fazemos uma sentena SQL. Executamos e se der como resultado que temos um registro encontrado na tabela de usurios, que o nome de usurio e chave correspondem com o de algum usurio. Logo com a linha
if ($_POST["salvar_chave"]=="1"){

Comprovamos se o visitante tinha pedido que se armazenasse a chave em seu computador. Ento, h que gerar as cookies correspondentes, que havamos comentado anteriormente neste artigo. Faremos em trs passos: Gero um nmero aleatrio para que nos sirva de marca. Insiro a marca aleatria na tabela de usurios, fazendo um update no registro do usurio autenticado que havamos detectado anteriormente. Gero e coloco no computador do usurio as duas cookies para salvar seu acesso no navegador: o identificador do usurio e a marca aleatria. Criamos as cookies para que se armazenem durante um ano no computador do usurio.
Nota: importante assinalar que, para colocar ou criar cookies no navegador do visitante, devemos faz-lo antes de terem enviado os cabealhos de http, ou seja, antes de ter escrito qualquer texto na pgina. Caso contrrio, poderia nos dar um erro de http headers already sent.

Por ltimo, veremos o cdigo PHP para ver se detectamos as cookies no navegador de um usurio autenticado anteriormente no sistema e salvo no computador do usurio.
//primeiro tenho que ver se o usurio est memorizado em uma cookie if (isset($_COOKIE["id_usuario_dw"]) && isset($_COOKIE["marca_aleatoria_usuario_dw"])){ //Tenho cookies memorizadas //ademais vou comprovar que essas variveis no estejam vazias if ($_COOKIE["id_usuario_dw"]!="" || $_COOKIE["marca_aleatoria_usuario_dw"]!=""){ //Vou ver se correspondem com algum usurio $ssql = "select * from usuario where id_usuario=" . $_COOKIE["id_usuario_dw"] . " and cookie='" . $_COOKIE["marca_aleatoria_usuario_dw"] . "' and cookie<>''"; $rs = mysql_query($ssql); if (mysql_num_rows($rs)==1){ echo "<b>Tenho um usurio correto em uma cookie</b>";

$usuario_encontrado = mysql_fetch_object($rs); echo "<br> o usurio nmero " . $usuario_encontrado->id_usuario . ", de nome " . $usuario_encontrado->usuario; //header ("Location: conteudos_protegidos_cookie.php"); } } }

Como primeiro passo, comprovo se existem as cookies com o identificador do usurio e a mencionada marca aleatria. Alm disso, fazemos uma comprovao adicional para ver se alguma das duas cookies contm um string vazio, porque nesse caso no esto salvas corretamente e no nos servem. Se tudo tiver ido bem, olhamos no banco de dado se o usurio com identificador determinado na cookie tem a marca aleatria igual que a que tinha a cookie do navegador do visitante. Ademais, na consulta no banco de dados tambm nos asseguramos que a marca aleatria seja distinta de "", porque ento um usurio que nunca havia pedido que se salvassem seus dados no computador. Se essa consulta dava um registro, que corresponde com um usurio que havia armazenado o computador e o usurio que estava autenticado anteriormente e salvo seu acesso. Concluso At aqui comentei tudo o que necessitamos saber para criar a infra-estrutura para que a pgina web lembre a chave ao usurio e no tenha que se autenticar cada vez que acessar o site. O cdigo que mostramos poderia se completar com uma srie de melhoras ou personalizaes para adapt-lo s nossas necessidades, mas certamente serve de guia para o interessado. Agora apresento o cdigo completo da pgina deste exemplo:
<? //conecto com o banco de dados $conn = mysql_connect(" servidor","usuario","chave"); //seleciono o BD mysql_select_db("banco de dados",$conn); //primeiro tenho que ver se o usurio est memorizado em uma cookie if (isset($_COOKIE["id_usuario_dw"]) && isset($_COOKIE["marca_aleatoria_usuario_dw"])){ //Tenho cookies memorizadas //ademais vou comprovar que essas variveis no estejam vazias if ($_COOKIE["id_usuario_dw"]!="" || $_COOKIE["marca_aleatoria_usuario_dw"]!=""){ //Vou ver se correspondem com algum usurio $ssql = "select * from usuario where id_usuario=" . $_COOKIE["id_usuario_dw"] . " and cookie='" . $_COOKIE["marca_aleatoria_usuario_dw"] . "' and cookie<>''"; $rs = mysql_query($ssql); if (mysql_num_rows($rs)==1){ echo "<b>Tenho um usurio correto em uma cookie</b>"; $usuario_encontrado = mysql_fetch_object($rs); echo "<br> o usurio nmero " . $usuario_encontrado->id_usuario . ", de nome " . $usuario_encontrado->usuario; //header ("Location: conteudos_protegidos_cookie.php"); } } } if ($_POST){ // que estamos recebendo dados pelo formulrio de autenticao (recibo de $_POST) //deveria comprovar se o usurio correto $ssql = "select * from usuario where usuario = '" . $_POST["usuario"] . "' and chave='" . $_POST["chave"] . "'"; //echo $ssql;

$rs = mysql_query($ssql); if (mysql_num_rows($rs)==1){ //TUDO CORRETO!! Detectei um usurio $usuario_encontrado = mysql_fetch_object($rs); //agora devo de ver se o usurio queria memorizar sua conta nesse computador if ($_POST["salvar_chave"]=="1"){ // que pediu para memorizar o usurio //1) crio uma marca aleatria no registro deste usurio //alimentamos o gerador de aleatrios mt_srand (time()); //geramos um nmero aleatrio $numero_aleatorio = mt_rand(1000000,999999999); //2) meto a marca aleatria na tabela de usurio $ssql = "update usuario set cookie='$numero_aleatorio' where id_usuario=" . $usuario_encontrado->id_usuario; mysql_query($ssql); //3) agora coloco uma cookie no computador do usurio com o identificador do usurio e a cookie aleatria setcookie("id_usuario_dw", $usuario_encontrado->id_usuario , time()+(60*60*24*365)); setcookie("marca_aleatoria_usuario_dw", $numero_aleatorio, time()+(60*60*24*365)); } echo "Autenticado corretamente"; //header ("Location: conteudos_protegidos_cookie.php"); }else{ echo "Falha de autenticao!"; echo "<p><a href='prova-cookies.php'>Voltar</a>"; } }else{ ?> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <title>cookies para detectar usuario</title> </head> <body> <form action="prova-cookies.php" method="post"> Usuario: <input type="text" name="usuario"> <br> Chave: <input type="text" name="chave"> <br> <input type="checkbox" name="salvar_chave" value="1"> Memorizar o usurio neste computador <br> <input type="submit" value="Entrar"> </form> <br> <br> <b>Usurios vlidos:</b> <br> <br> User: pepe <br> Chave: 1234 <br> <br> User: juan <br> Chave: 1111 </body> </html> <? } ?>

Por ltimo, deixo aqui o link para ver o exemplo criado em funcionamento.

Você também pode gostar