Arquivar

Posts Etiquetados ‘cookie’

CGI: Trabalhando com Cookies (Autenticação/Login) Parte II

16 Agosto, 2008 Whitesnake 2 comentários

Para começarmos a desenvolver nossa Central de Autenticação, vamos definir o módulo basico que iremos trabalhar.

use CGI;

Instanciando o CGI em $my_cgi por exemplo, podemos utilizar todos os seus recursos, inclusive o cookie( ) que será responsável pela captura dos cookies.

Assim sendo, podemos iniciar nosso CGI indicando uma condição que verifica se há um determinado cookie setado na maquina do usuário ou não. Ou seja, este seria o motor do programa, a parte de autenticação, que poderia ser algo como:

if ($cgi->cookie(“login”) eq “login” && $cgi->cookie(“senha”) eq “senha”){
   #      ( CONTEUDO RESTRITO)      #
}else{
  #      (TELA DE LOGIN)       #
}

Com este código ja podemos liberar ou restringir acesso para os usuários.
Mas, com certeza o script ainda não está pronto. Sim, falta a parte principal! A de Setar/Definir Cookies.

Como iniciamos nosso programa com uma condicional, caso esta retorne falso, faz sentido colocarmos uma tela de login para que usuário então, realize o login, criando assim um cookie de autenticação.

Nosso formulário pode ser definido apenas com:

<form method=’post’ action=’?login’>
     <h3>Autenticação</h3>
     Login: <input type=text name=’login’ value=”" size=8>
     Senha: <input type=password name=’senha’ value=”" size=8>
    <input type=”submit” value=”OK”>
</form>

Aqui entrará então os dados do usuário, que serão transmitidos até a querystring login.
Dentro dessa querystring então, poderemos capturar o login e senha atribuídos e se forem autênticos salvaremos os valores junto ao Cookie do usuário.

Note como realizar isto:

if($ENV{QUERY_STRING} eq “login”){     # Quando o usuário envia o formulário,
  if ($cgi->param(“login”) eq “login” && $cgi->param(“senha”) eq “senha”){ # Se o login é autêntico

     #   IREMOS SETAR O COOKIE   #
     &addCookie;
 }else{           # Senão

   # MOSTRAREMOS MENSAGEM DE ERRO #

 }
}

Os parâmetros de verificação de login são exatamente iguais aos utilizados no início do programa, porém, dessa vez não faz a checagem com os dados do cookie, mas com os dados do formulário recebido. Quando a condição é falsa, poderemos mostrar uma mensagem de erro, dizendo que o login/senha informados estão incorretos, mas caso retorne verdadeiro, para facilitar, iremos chamar uma função que realizará a tarefa de gravar o cookie: &addcookie.

Vamos ao código dessa função:

  $cookie1=$cgi->cookie(-name=>’login’,    # Define o nome do novo cookie
                                         -value=>$cgi->param(“login”), # Define o seu valor                
                      -expires=>’+30d’, # Expira em trinta dias
                      -path=>’/',                          # Servirá para todas as nossas páginas
   ); 

  $cookie2=$cgi->cookie(-name=>’senha’,    # Define o nome do novo cookie
                                         -value=>$cgi->param(“senha”), # Define o seu valor 
                                         -expires=>’+30d’, # Expira em trinta dias
                      -path=>’/',                          # Servirá para todas as nossas páginas
   );   

print $cgi->header(
      -cookie=>[$cookie1,$cookie2], # Salvamos os cookies
       );
}

Notou como não é nenhum bicho de sete cabeças? Vamos a explicação agora.
O atributo name, como o próprio nome já diz, é onde definimos o nome do cookie. Este primeiro, é o do login que salvaremos no browser do usuário.

Em seguida, vem o seu valor, com o qual será obtido depois pela chamada do método CGI através do atributo cookie([NOME]).

 O outro atributo, expires é opcional, ele define qual a duração do cookie, se não especificarmos nenhum valor, ele valerá apenas enquanto o usuário estiver na página.

Por último, o path, é o caminho inicial de onde o cookie poderá ser lido. Por exemplo,  se definirmos /cgi-bin/, os arquivos contidos na pasta, ou por exemplo, em /cgi-bin/algumapasta/ reconhecerão o cookie, mas os arquivos em /htdocs/ não terão acesso. Isto é meio confuso, por este motivo, o padrão é ‘/’ que permite acesso a todo o conteúdo.

Note que realizamos a criação de dois cookies, login e senha, por isso realizamos o processo duas vezes.

Agora, com os dados definidos, devemos mandar a resposta para o browser, e esta, como parte do cabeçalho, caso você esteja trabalhando sem o CGI, lembre-se que deverá vir antes do “Content-type”.

No nosso caso utilizaremos a função header( ) do CGI para implantar o cookie para nós.

Para isto foi necessário apenas informar os dois cookies através do atributo cookie.

Bem, com isso podemos ter um sistema de autenticação funcional que utiliza cookies. Agora basta soltar a criatividade, e implantá-lo em seus sistemas.

Abraços.


Veja Funcionando:

[ Sistema de Autenticação por Cookies

Login: admin | Senha: admin

 


Veja o Código Completo:
(autenticacao.cgi)

#!/usr/bin/perl
use CGI;
###########################################################

$cgi=new CGI(); # Criamos uma instância em CGI
$login=$cgi->cookie(“login”); # Este parâmetro obtem o valor
do atributo login dentro do cookie
if (!$ENV{QUERY_STRING}){ # Em cada pagina que o usuário visitar
if ($cgi->cookie(“login”) eq “admin” && $cgi->cookie(“senha”)
eq “admin”){ # valida o cookie
&home; # passa para a função restrita
}else{
&login;
}
}
if ($ENV{QUERY_STRING} eq “restrito”){ # Em cada pagina que o usuário
visitar
if ($cgi->cookie(“login”) eq “admin” && $cgi->cookie(“senha”)
eq “admin”){ # valida o cookie
&restrito; # passa para a função restrita
}else{
&login;
}
}
if($ENV{QUERY_STRING} eq “login”){ # Quando o usuário envia
o formulário, verificamos…
if ($cgi->param(“login”) eq “admin” && $cgi->param(“senha”)
eq “admin”){ # Se mandou login e senha corretos…
&addCookie; # Adiciona cookie
}else{ # Senão
$msg = “<font color=’red’>Login/Senha inválidos!</font>”;
# Mensagem de erro
&login; # Redireciona para a tela de login
}
}

##############################
########## FUNÇOES ###########
##############################
sub addCookie{
$inicial=”?”;
$codigo=int rand(100000); # Pega um número qualquer
$cookie1=$cgi->cookie(-name=>’login’, # Define o nome do novo cookie
-value=>$cgi->param(“login”), # Define o valor
-expires=>’+’.$cgi->param(“expira”), # Expira em tempo especificado

-path=>’/', # Servirá para todas as nossas páginas
);
$cookie2=$cgi->cookie(-name=>’senha’, # Define o nome do novo cookie
-value=>$cgi->param(“senha”), # Define o valor
-expires=>’+’.$cgi->param(“expira”), # Expira em tempo especificado

-path=>’/', # Servirá para todas as nossas páginas
);
print $cgi->header(
-cookie=>[$cookie1,$cookie2], # Salvamos os cookies
-location=>$inicial); # Vai para pagina inicial
}

sub home{
print qq|Content-type:text/html\n\n
<html>
<head>
<title>Home</title>
<meta charset=”iso-8859-1″ />
</head>
<body>
Home \| <a href=”?restrito”>Conteudo Restrito</a>
<h1>Home</h1>
<p>Olá você esta logado como <b>$login</b>.</p>
<p>Você pode visitar os links acima/atualizar esta página
várias vezes, mas quando
o tempo expirar, você voltará à tela de login.</p>

</body>
</html>
|;
}
sub login{
print qq|Content-type:text/html\n\n
<html>
<head>
<title>Login</title>
<meta charset=”iso-8859-1″/>
</head>
<body>
<a href=”?”>Home</a> \| <a href=”?restrito”>Conteudo
Restrito</a>
<p>$msg</p>
<form method=’post’ action=’?login’>
<table style=text-align:center id=’autbox’>
<tr>
<td colspan=2>Autenticação</td>
</tr>
<tr><td>Login:</td><td>
<input type=text name=’login’ value=”admin” size=8></td>
</tr>
<tr><td>Senha:</td><td>
<input type=password name=’senha’ value=”admin” size=8></td>
</tr>
<tr><td>Expira em:</td><td>
<select name=”expira”>
<option value=”30s”>30 segundos</option>
<option value=”1m”>Um minuto</option>
<option value=”5m”>5 minutos</option>
<option value=”10m”>10 minutos</option>
<option value=”15m”>15 minutos</option>
<option value=”1h”>Uma hora</option>
<option value=”1d”>Um dia</option>
<option value=”1M”>Um mês</option>
</select></td>
</tr>
<tr><td colspan=2>
<input type=”submit” value=”OK”></td>
</tr>
</table>
</form>
</body>
</html>|;
}
sub restrito{
print qq|Content-type:text/html\n\n
<html>
<head>
<title>Conteúdo Restrito</title>
<meta charset=”iso-8859-1″ />
</head>
<body>
<a href=”?”>Home</a> \| Conteudo Restrito
<h1>Conteúdo Restrito</h1>
<p>Olá você esta logado como <b>$login</b>.</p>
<p>Você pode visitar os links acima/atualizar esta página
várias vezes, mas quando
o tempo expirar, você voltará à tela de login.</p>
</body>
</html>|;
}

CGI: Trabalhando com Cookies (Autenticação/Login) Parte I

16 Agosto, 2008 Whitesnake 3 comentários

Uma boa definição para cookie seria: um conjunto de informações específicas sobre cada usuário gravadas em seu próprio ambiente. Ou seja, o cookie é algo colocado no computador do usuário, e não do servidor onde está sendo executado.

Quais as vantagens?
Por exemplo, se você está frequentemente acessando um site que requer login e senha, não é desconfortável ter que todo dia digitar o mesmo login e a mesma senha?
Sim. Mas você talvez argumente, mas se não for dessa forma, como ele (o site) vai saber que sou eu quem está acessando? Aí que entra o cookie nessa história!

Ao efetuar o primeiro login muitos sites, a exemplo do Google, oferecem a opção ‘Salvar as minhas informações neste computador’, e advinhe de que forma isto é feito?

Isso mesmo! Através de cookies! O cookie irá gravar em seu computador os dados do login e senha especificados na primeira visita. Assim, sempre quando você acessa um site com esse recurso, você entra automaticamente, sem ter que fazer o login novamente. Por quê!? Por que o login já foi autenticado utilizando as informações gravadas em seu cookie!

Notou agora a utilidade dos cookies?
Vamos ver um exemplo sobre como utilizá-lo em um sistema de autenticação.


O meio mais fácil de se trabalhar com cookies é por utilizar o módulo Perl CGI.

Como ele possui várias interfaces para o protocolo HTTP, será de extrema utilidade para nós, já que trabalharemos com um padrão de protocolo.

Vamos primeiramente saber como o browser detecta um cookie.

O cookie sempre é transmitido pelo cabeçalho do HTTP, ou seja, se uma página possui um determinado cookie, esta é uma das primeiras informações a serem recebidas pelo servidor. Da mesma forma acontece com o usuário, quando o servidor cria um cookie, um dos primeiros argumentos a ser recebido pelo browser do usuário é justamente o cookie.

Dessa forma, devemos ter em mente que nosso script CGI não poderá iniciar como usualmente, definindo o cabeçalho de conteúdo (“Content-type:text/html“) na primeira instrução, pois haverá pontos onde deveremos enviar primeiramente o cookie.

Vamos ver todos estes pontos na prática no próximo artigo, que utilizará como exemplo um sistema de autenticação restrito que utilizará cookies.

On the Fly – O Que É?

4 Agosto, 2008 Whitesnake 8 comentários

On the fly é uma expressão em inglês que têm como significado os termos: dinâmicamente, às pressas, sempre mudando.

Em termos de programação, o On-the-fly significa algo criado, ou modificado dinâmicamente somente quando requisitamos.

Um exemplo de sistema on-the-fly é o validador de códigos em imagem.

Este tipo de validador, gera uma imagem diferente a cada atualização da página. É imprevisível quantas imagens um usuário poderá necessitar até que este entre com um código correto, por isso não faz sentido armazená-las, pois caso contrário, em um grande site, isto facilmente poderia causar uma sobrecarga.

Mas o On-the-fly resolve esta questão! Uma vez que a imagem fora criada, esta permanesse apenas no cache do usuário. Caso este venha a atualizar a página, uma nova imagem é gerada.

Veja funcionando:

[ Validador On-the-Fly


 

Veja o Código Completo:
(validador.cgi)

 #!/usr/bin/perl
use CGI;
use CGI::Carp “fatalsToBrowser”;
use Image::Magick;
###########################################################

$format = “jpeg”; # Formato de saída

$qs = $ENV{QUERY_STRING}; # Pegamos a querystring

## Lemos o buffer
read(STDIN, $buffer, $ENV{‘CONTENT_LENGTH’});
@conteudo2 = split(/&/, $ENV{QUERY_STRING});
foreach $par (@conteudo2) {
        ($campo, $valor) = split(/=/, $par);
        $valor =~ tr/+/ /;
        $valor =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack(“C”, hex($1))/eg;
        $QUERY{$campo} = $valor;
}

$cgi=new CGI( ); # Criamos uma instância em CGI

if (!$ENV{QUERY_STRING}){ # Se não há querystring
   &addcookie; # Gera novo cookie
   &form; # Mostra formulário
}elsif($QUERY{cod}){ # Se há querystring
  if ($cgi->cookie(‘codigo’) eq $QUERY{cod}){
   # Se o código digitado corresponde ao código no cookie
   &addcookie; # Gera novo cookie 
   # Se corresponde, mostra correto
   print  “<font color=green><h3>Código correto!</h3></font>”; 
   &form; # Mostra formulário
  }else{  # Senão
   &addcookie; # Gera novo cookie
   print  “<font color=red><h3>Código errado!</h3></font>”; # Mostra errado
   &form; # Mostra formulário
  }

}elsif($QUERY{gerar}){ # Se mandou gerar….

  $rand=$cgi->cookie(‘codigo’); # Pega o numero que irá mostrar
  $novo  = Image::Magick-> new(size=>’100×65′);
  # Cria imagem com as dimensões desejadas
  $imagem = $novo-> Read(‘gradient:#CCCCCC-#EEEEEE’);
  # Lê a imagem e coloca-a em uma variável com um fundo degradê
  $imagem=$novo-> Raise(‘4×4′); # Adiciona um efeito de relevo
  $imagem=$novo->MotionBlur(angle=>60,radius=>8,sigma=>3);
  # Adiciona um efeito de borrar
  $imagem=$novo-> Annotate( font => ‘/home/www/HATTEN.ttf’,# Caminho para fonte
fill        => ‘black’,             # Cor da fonte
                                                 pointsize  => 20,               # Tamanho da fonte
                                                 gravity      => ‘Center’,       # Alinhamento
                                                 text          => $rand,          # Escreve o número
  );

  print “Content-type:image/$format\n\n”;
  # Imprime o cabeçalho com o devido formato
  binmode STDOUT;                                 
  # Converte a saída para binario

  $imagem=$novo->Write( “$format:-” );
  # Mostra a imagem no formato escolhido

}

sub form{
 # Mostra na tela
 print qq|<p>Digite o código:</p>
 <img src=?gerar=num />
 <form method=’get’>
  <input type=text name=’cod’ size=8>
  <input type=submit value=’ok’>
 </form>
 |;
}

sub addcookie{
   $codigo=int rand(100000); # Pega um número qualquer
   $cookie=$cgi->cookie(-name=>’codigo’, # Novo cookie
  -value=>$codigo,                    
  -expires=>’+1m’,                     # Expira em 1 minuto
  -path=>’/',
   ); 
   print $cgi->header(-cookie=>$cookie);  # Salvamos o cookie
}