Recentemente desenvolvi uma classe para trabalhar ocm autenticação por imagens, e hoje estou disponibilizando-a aqui para quem estiver interessado(a) em usá-la. :)
Os caracteres da imagem são gerados usando algumas fontes True Type presentes no diretório de fontes, cujo nome é especificado na propriedade $fonts_dir da classe ImgAuth.
O código est´[a com vários comentários, mas se alguém tiver alguma dúvida, pode perguntar. Vou postar primeiro a Classe depois posto os exemplos de uso.
class.img_auth.php => arquivo com a classe responsável por todas as ações do sistema
<?php
#############################################
# #
# Autor: Roberto Beraldo Chaiben (Beraldo) #
# E-Mail: rbchaiben[arroba]yahoo.com.br #
# #
#############################################
/****************************************
* *
* Desenvolvido para PHP 5.0 ou superior *
* *
****************************************/
/*
Esta classe se destina à criação de sistema de autenticação por imagem. Ela possui funções (métodos) para a criação da imagem, armazenagem do código gerado em uma variável de sessão e comparação entre o código digitado e o armazenado na sessão.
*/
class ImgAuth
{
//tipo da imagem (jpg, gif ou png)
private $img_type = "png";
//array com as cores utilizadas. Esse array é preenchido na função SetColors()
private $colors = array();
//array com cores de fundo e de estilização, não usadas no código gerado na imagem. Array preenchido na função SetColors()
private $style = array();
//retorno da função imagecreate()
private $im;
//largura da imagem
private $img_width = 300;
//altura da imagem
private $img_height = 100;
//código gerado na imagem. Essa propriedade é gerada na função CodeRand()
private $code = "";
//número de caracteres do código gerado
private $code_lenght = 5;
//amostra. Todas as letras e números que serão utilizados para gerar o código. Esse array é preenchido na função SetSample()
private $sample = array();
//nome do diretório das fontes True Type que serão utilizadas
private $fonts_dir = "fonts/";
//array com as fontes True Type do diretório de fontes. Esse array é preenchido na função SetFonts().
private $fonts = array();
/*
void __construct([string img_type])
Realiza as ações necessárias para inicializar o sistema de autenticação.
O parâmetro opcional 'img_type' define o tipo da imagem. Ele pode conter um destes valores:
- 'jpg' ou 'jpeg' -> cria uma imagem JPEG
- 'gif' -> cria uma imagem GIF
- 'png' -> cria uma imagem PNG
* Se não for especificado um valor, adotar-se-á o tipo definido na propriedade $img_type da classe.
*/
public function __construct($img_type = NULL)
{
if (!$this->CheckFontsDir())
{
echo "<p>Erro. Função <strong>". __FUNCTION__ ."()</strong>: O diretório das fontes não foi encontrado ou ele não é um diretório válido.</p>";
return false;
}
$this->im = imagecreate($this->img_width, $this->img_height);
//define o tipo da imagem
$this->SetImgType(strtolower($img_type));
//preenche o array $fonts com as fontes do dirertório de fontes
$this->SetFonts();
//preenche o array $colors com algumas cores que serão utilizadas para gerar o código na imagem
$this->SetColors();
//cria a amostra de caracteres disponíveis para a geração do código
$this->SetSample();
}
/*
void SetImgType(string img_type)
Define o tipo da imagem, conforme o valor de 'img_type'.
*/
private function SetImgType($img_type)
{
switch ($img_type)
{
case "gif":
$this->img_type = "gif";
break;
case "png":
$this->img_type = "png";
break;
case "jpg":
case "jpeg":
$this->img_type = "jpg";
break;
}
}
/*
bool CheckFontsDir()
Verifica se o diretório das fontes True Type é válido.
*/
private function CheckFontsDir()
{
//adiciona uma barra ao final do nome do diretório de fontes, se não existir
if (substr($this->fonts_dir, -1) != "/")
{
$this->fonts_dir .= "/";
}
//verifica se o diretório existe e se realmente é um diretório válido
if (!file_exists($this->fonts_dir) || !is_dir($this->fonts_dir))
{
return false;
}
return true;
}
/*
bool SetFonts()
Lê o diretório das fontes e adiciona em $fonts o nome das fontes True Type contidas nele.
*/
private function SetFonts()
{
//abre o diretório de fontes
$open = opendir($this->fonts_dir);
while (false !== ($file = readdir($open)))
{
if ($file == "." || $file == ".." || is_dir($this->fonts_dir . $file))
continue;
//identifica a extensão do arquivo
$ext = strtolower(end(explode(".", $file)));
//ttf = extensão de arquivos de fontes True Type
if ($ext != "ttf")
continue;
//adiciona a fonte ao array $fonts
$this->fonts[] = $file;
}
closedir($open);
}
/*
void SetColors()
Gera o array com as cores utilizadas na imagem.
*/
private function SetColors()
{
//cor de fundo
$this->style['bg'] = imagecolorallocate($this->im, 0xC0, 0xC0, 0xC0);
//cor das linhas do fundo
$this->style['darkgray'] = imagecolorallocate($this->im, 0x90, 0x90, 0x90);
//cores para se utilizarem no código da imagem
$this->colors['black'] = imagecolorallocate($this->im, 0, 0, 0);
$this->colors['blue'] = imagecolorallocate($this->im, 0, 0, 255);
$this->colors['darkblue'] = imagecolorallocate($this->im, 0, 0, 200);
$this->colors['red'] = imagecolorallocate($this->im, 255, 0, 0);
$this->colors['darkred'] = imagecolorallocate($this->im, 200, 0, 0);
$this->colors['green'] = imagecolorallocate($this->im, 0, 255, 0);
$this->colors['darkgreen'] = imagecolorallocate($this->im, 0, 200, 0);
$this->colors['yellow'] = imagecolorallocate($this->im, 255, 255, 0);
$this->colors['navy'] = imagecolorallocate($this->im, 0x00, 0x00, 0x80);
$this->colors['darknavy'] = imagecolorallocate($this->im, 0x00, 0x00, 0x50);
}
/*
void SetSample()
Gera a amostra de letras e números utilizada para gerar o código.
*/
private function SetSample()
{
//letras minúsculas
$letras_min = range("a", "z");
//letras maiúsculas
$letras_mai = range("A", "Z");
//números. Não usaremos o zero pois ele pode ser confundido com a letra O.
$nums = range(1, 9);
//retira algumas letras que possam gerar confusões
unset($letras_min[array_search("l", $letras_min)]);
unset($letras_min[array_search("o", $letras_min)]);
unset($letras_mai[array_search("I", $letras_mai)]);
unset($letras_mai[array_search("O", $letras_mai)]);
//array com todas as letras e números que utilizaremos
$this->sample = array_merge($letras_min, $letras_mai, $nums);
}
/*
void ImgHeader()
Adiciona o cabeçalho da imagem, conforme o valor da propriedade $img_type.
*/
public function ImgHeader()
{
switch ($this->img_type)
{
case "jpg":
header("Content-Type: image/jpeg");
break;
case "gif":
header("Content-Type: image/gif");
break;
case "png":
header("Content-Type: image/png");
break;
}
}
/*
void ImgBg()
Desenhas linhas no fundo (background) da imagem, para dificultar a leitura do código por partes de robôs (bots).
*/
public function ImgBg()
{
//posição X da primeira linha
$w = 10;
while ($w < $this->img_width)
{
$x_s = rand($w, $this->img_width);
$x_f = rand($w, $this->img_width);
//desenha uma linha obliqüa no sentido decrescente
imageline($this->im, $x_s, 0, $x_f, $this->img_height, $this->style['darkgray']);
//desenha uma linha orizontal
imageline($this->im, 0, $w, $this->img_width, $w, $this->style['darkgray']);
$w += 20;
$x_s = rand(0, $this->img_width);
$x_f = rand(0, $this->img_width);
//desenha uma linha obliqüa no sentido crescente
imageline($this->im, $x_s, 0, $x_f, $this->img_height, $this->style['darkgray']);
}
}
/*
void CreateImg()
Gera a imagem e a destrói, encerrando o script.
*/
public function CreateImg()
{
//armazena o código gerado em uma variável de sessão
$this->StoreCodeInSession();
switch ($this->img_type)
{
case "jpg":
imagejpeg($this->im, '', 95);
break;
case "gif":
imagegif($this->im);
break;
case "png":
imagepng($this->im);
break;
}
imagedestroy($this->im);
}
/*
string CodeRand()
Gera o código.
*/
private function CodeRand()
{
$string = $this->sample[array_rand($this->sample)];
$this->code .= $string;
return $string;
}
/*
void SetImgCode()
Escreve o código na imagem.
*/
public function SetImgCode()
{
//cria o fundo da imagem
$this->ImgBg();
//posição Y do código na imagem
$y = round($this->img_height / 1.4);
//tamanho da fonte
$size = round($this->img_height / 2.2);
//posição X inicial
$w = -5;
for ($i = 0; $i <= $this->code_lenght; $i++)
{
//sorteia um caractere
$code = $this->CodeRand();
//sorteia uma cor
$color = $this->colors[array_rand($this->colors)];
//sorteia uma fonte
$font = $this->fonts_dir . $this->fonts[array_rand($this->fonts)];
//define uma angulação para o caractere
$angle = rand(-12, 12);
//adiciona o caractere à imagem
imagettftext($this->im, $size, $angle, ($w + 20), $y, $color, $font, $code);
//aumenta o valor de $w, para ser utilizado no próximo caractere
$w += 43;
}
}
/*
void StoreCodeInSession()
Armazena na sessão o código gerado.
*/
private function StoreCodeInSession()
{
//se não houver uma sessão inicializada, inicia-a
if (!isset($_SESSION))
{
session_start();
}
$_SESSION['auth_code'] = $this->code;
}
/*
bool CodeCompare(string inputed_code, bool case_sensitive)
Esse método verifica se o valor de inputed_code (código digitado pelo visitante) é igual ao gerado na imagem e armazenado na sessão. Retorna TRUE se os código forem iguais; caso contrário retorna FALSE.
O parâmetro case_sensitive define se a verificação deve diferenciar maiúsculas de minúsculas. Por padrão, esse argumaneto tem o valor TRUE. Se você quiser que a verificação ignore a diferença entre maiúsculas e minússculas, defina o valor desse parâmetro para FALSE.
*/
public function CodeCompare($inputed_code, $case_sensitive = true)
{
//retira caracteres diferentes de letras e números
$inputed_code = preg_replace("/[^0-9a-zA-Z]/i", "", $inputed_code);
$input = ($case_sensitive === false) ? strtolower($inputed_code) : $inputed_code;
$auth_code = ($case_sensitive === false) ? strtolower($_SESSION['auth_code']) : $_SESSION['auth_code'];
if ($input == $auth_code)
{
return true;
}
else
{
return false;
}
}
}
?>
img.php => arquivo responsável por gerar a imagem. Ele atuará como uma imagem propriamente dita
index.php => um arquivo HTML comum (coloquei .php somente porque costumo usar um arquivo de inicialização de sistema, sendo necessário manter a index com extensão PHP) com um campo para digitar o códifgo e a tag img onde será mostrada a imagem dinâmica.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=iso-8859-1" />
<title>Formulário</title>
</head>
<body>
<form method="post" action="auth.php">
<p>Digite no campo abaixo o código que aparece na imagem a saeguir. <strong>O sistema diferencia letras maiúsculas de minúsculas, ou seja "a" é diferente de "A".</strong></p>
<input type="text" name="code" />
<br /><br />
<img src="img.php" alt="" />
<br /><br />
<input type="submit" value="Enviar" />
</form>
</body>
</html>
* Notem que no src da tag img coloquei o arquivo img.php. Lembram-se de que eu disse que o img.php atuaria como uma imagem propriamente dita? De fato, atuará. ;) :D
auth.php => Arquivo responsável por receber o código digitado e compará-lo com o armazenado na sessão
Pergunta
Beraldo
Olá, pessoal. :D
Recentemente desenvolvi uma classe para trabalhar ocm autenticação por imagens, e hoje estou disponibilizando-a aqui para quem estiver interessado(a) em usá-la. :)
Os caracteres da imagem são gerados usando algumas fontes True Type presentes no diretório de fontes, cujo nome é especificado na propriedade $fonts_dir da classe ImgAuth.
O código est´[a com vários comentários, mas se alguém tiver alguma dúvida, pode perguntar. Vou postar primeiro a Classe depois posto os exemplos de uso.
class.img_auth.php => arquivo com a classe responsável por todas as ações do sistema
<?php ############################################# # # # Autor: Roberto Beraldo Chaiben (Beraldo) # # E-Mail: rbchaiben[arroba]yahoo.com.br # # # ############################################# /**************************************** * * * Desenvolvido para PHP 5.0 ou superior * * * ****************************************/ /* Esta classe se destina à criação de sistema de autenticação por imagem. Ela possui funções (métodos) para a criação da imagem, armazenagem do código gerado em uma variável de sessão e comparação entre o código digitado e o armazenado na sessão. */ class ImgAuth { //tipo da imagem (jpg, gif ou png) private $img_type = "png"; //array com as cores utilizadas. Esse array é preenchido na função SetColors() private $colors = array(); //array com cores de fundo e de estilização, não usadas no código gerado na imagem. Array preenchido na função SetColors() private $style = array(); //retorno da função imagecreate() private $im; //largura da imagem private $img_width = 300; //altura da imagem private $img_height = 100; //código gerado na imagem. Essa propriedade é gerada na função CodeRand() private $code = ""; //número de caracteres do código gerado private $code_lenght = 5; //amostra. Todas as letras e números que serão utilizados para gerar o código. Esse array é preenchido na função SetSample() private $sample = array(); //nome do diretório das fontes True Type que serão utilizadas private $fonts_dir = "fonts/"; //array com as fontes True Type do diretório de fontes. Esse array é preenchido na função SetFonts(). private $fonts = array(); /* void __construct([string img_type]) Realiza as ações necessárias para inicializar o sistema de autenticação. O parâmetro opcional 'img_type' define o tipo da imagem. Ele pode conter um destes valores: - 'jpg' ou 'jpeg' -> cria uma imagem JPEG - 'gif' -> cria uma imagem GIF - 'png' -> cria uma imagem PNG * Se não for especificado um valor, adotar-se-á o tipo definido na propriedade $img_type da classe. */ public function __construct($img_type = NULL) { if (!$this->CheckFontsDir()) { echo "<p>Erro. Função <strong>". __FUNCTION__ ."()</strong>: O diretório das fontes não foi encontrado ou ele não é um diretório válido.</p>"; return false; } $this->im = imagecreate($this->img_width, $this->img_height); //define o tipo da imagem $this->SetImgType(strtolower($img_type)); //preenche o array $fonts com as fontes do dirertório de fontes $this->SetFonts(); //preenche o array $colors com algumas cores que serão utilizadas para gerar o código na imagem $this->SetColors(); //cria a amostra de caracteres disponíveis para a geração do código $this->SetSample(); } /* void SetImgType(string img_type) Define o tipo da imagem, conforme o valor de 'img_type'. */ private function SetImgType($img_type) { switch ($img_type) { case "gif": $this->img_type = "gif"; break; case "png": $this->img_type = "png"; break; case "jpg": case "jpeg": $this->img_type = "jpg"; break; } } /* bool CheckFontsDir() Verifica se o diretório das fontes True Type é válido. */ private function CheckFontsDir() { //adiciona uma barra ao final do nome do diretório de fontes, se não existir if (substr($this->fonts_dir, -1) != "/") { $this->fonts_dir .= "/"; } //verifica se o diretório existe e se realmente é um diretório válido if (!file_exists($this->fonts_dir) || !is_dir($this->fonts_dir)) { return false; } return true; } /* bool SetFonts() Lê o diretório das fontes e adiciona em $fonts o nome das fontes True Type contidas nele. */ private function SetFonts() { //abre o diretório de fontes $open = opendir($this->fonts_dir); while (false !== ($file = readdir($open))) { if ($file == "." || $file == ".." || is_dir($this->fonts_dir . $file)) continue; //identifica a extensão do arquivo $ext = strtolower(end(explode(".", $file))); //ttf = extensão de arquivos de fontes True Type if ($ext != "ttf") continue; //adiciona a fonte ao array $fonts $this->fonts[] = $file; } closedir($open); } /* void SetColors() Gera o array com as cores utilizadas na imagem. */ private function SetColors() { //cor de fundo $this->style['bg'] = imagecolorallocate($this->im, 0xC0, 0xC0, 0xC0); //cor das linhas do fundo $this->style['darkgray'] = imagecolorallocate($this->im, 0x90, 0x90, 0x90); //cores para se utilizarem no código da imagem $this->colors['black'] = imagecolorallocate($this->im, 0, 0, 0); $this->colors['blue'] = imagecolorallocate($this->im, 0, 0, 255); $this->colors['darkblue'] = imagecolorallocate($this->im, 0, 0, 200); $this->colors['red'] = imagecolorallocate($this->im, 255, 0, 0); $this->colors['darkred'] = imagecolorallocate($this->im, 200, 0, 0); $this->colors['green'] = imagecolorallocate($this->im, 0, 255, 0); $this->colors['darkgreen'] = imagecolorallocate($this->im, 0, 200, 0); $this->colors['yellow'] = imagecolorallocate($this->im, 255, 255, 0); $this->colors['navy'] = imagecolorallocate($this->im, 0x00, 0x00, 0x80); $this->colors['darknavy'] = imagecolorallocate($this->im, 0x00, 0x00, 0x50); } /* void SetSample() Gera a amostra de letras e números utilizada para gerar o código. */ private function SetSample() { //letras minúsculas $letras_min = range("a", "z"); //letras maiúsculas $letras_mai = range("A", "Z"); //números. Não usaremos o zero pois ele pode ser confundido com a letra O. $nums = range(1, 9); //retira algumas letras que possam gerar confusões unset($letras_min[array_search("l", $letras_min)]); unset($letras_min[array_search("o", $letras_min)]); unset($letras_mai[array_search("I", $letras_mai)]); unset($letras_mai[array_search("O", $letras_mai)]); //array com todas as letras e números que utilizaremos $this->sample = array_merge($letras_min, $letras_mai, $nums); } /* void ImgHeader() Adiciona o cabeçalho da imagem, conforme o valor da propriedade $img_type. */ public function ImgHeader() { switch ($this->img_type) { case "jpg": header("Content-Type: image/jpeg"); break; case "gif": header("Content-Type: image/gif"); break; case "png": header("Content-Type: image/png"); break; } } /* void ImgBg() Desenhas linhas no fundo (background) da imagem, para dificultar a leitura do código por partes de robôs (bots). */ public function ImgBg() { //posição X da primeira linha $w = 10; while ($w < $this->img_width) { $x_s = rand($w, $this->img_width); $x_f = rand($w, $this->img_width); //desenha uma linha obliqüa no sentido decrescente imageline($this->im, $x_s, 0, $x_f, $this->img_height, $this->style['darkgray']); //desenha uma linha orizontal imageline($this->im, 0, $w, $this->img_width, $w, $this->style['darkgray']); $w += 20; $x_s = rand(0, $this->img_width); $x_f = rand(0, $this->img_width); //desenha uma linha obliqüa no sentido crescente imageline($this->im, $x_s, 0, $x_f, $this->img_height, $this->style['darkgray']); } } /* void CreateImg() Gera a imagem e a destrói, encerrando o script. */ public function CreateImg() { //armazena o código gerado em uma variável de sessão $this->StoreCodeInSession(); switch ($this->img_type) { case "jpg": imagejpeg($this->im, '', 95); break; case "gif": imagegif($this->im); break; case "png": imagepng($this->im); break; } imagedestroy($this->im); } /* string CodeRand() Gera o código. */ private function CodeRand() { $string = $this->sample[array_rand($this->sample)]; $this->code .= $string; return $string; } /* void SetImgCode() Escreve o código na imagem. */ public function SetImgCode() { //cria o fundo da imagem $this->ImgBg(); //posição Y do código na imagem $y = round($this->img_height / 1.4); //tamanho da fonte $size = round($this->img_height / 2.2); //posição X inicial $w = -5; for ($i = 0; $i <= $this->code_lenght; $i++) { //sorteia um caractere $code = $this->CodeRand(); //sorteia uma cor $color = $this->colors[array_rand($this->colors)]; //sorteia uma fonte $font = $this->fonts_dir . $this->fonts[array_rand($this->fonts)]; //define uma angulação para o caractere $angle = rand(-12, 12); //adiciona o caractere à imagem imagettftext($this->im, $size, $angle, ($w + 20), $y, $color, $font, $code); //aumenta o valor de $w, para ser utilizado no próximo caractere $w += 43; } } /* void StoreCodeInSession() Armazena na sessão o código gerado. */ private function StoreCodeInSession() { //se não houver uma sessão inicializada, inicia-a if (!isset($_SESSION)) { session_start(); } $_SESSION['auth_code'] = $this->code; } /* bool CodeCompare(string inputed_code, bool case_sensitive) Esse método verifica se o valor de inputed_code (código digitado pelo visitante) é igual ao gerado na imagem e armazenado na sessão. Retorna TRUE se os código forem iguais; caso contrário retorna FALSE. O parâmetro case_sensitive define se a verificação deve diferenciar maiúsculas de minúsculas. Por padrão, esse argumaneto tem o valor TRUE. Se você quiser que a verificação ignore a diferença entre maiúsculas e minússculas, defina o valor desse parâmetro para FALSE. */ public function CodeCompare($inputed_code, $case_sensitive = true) { //retira caracteres diferentes de letras e números $inputed_code = preg_replace("/[^0-9a-zA-Z]/i", "", $inputed_code); $input = ($case_sensitive === false) ? strtolower($inputed_code) : $inputed_code; $auth_code = ($case_sensitive === false) ? strtolower($_SESSION['auth_code']) : $_SESSION['auth_code']; if ($input == $auth_code) { return true; } else { return false; } } } ?>img.php => arquivo responsável por gerar a imagem. Ele atuará como uma imagem propriamente dita index.php => um arquivo HTML comum (coloquei .php somente porque costumo usar um arquivo de inicialização de sistema, sendo necessário manter a index com extensão PHP) com um campo para digitar o códifgo e a tag img onde será mostrada a imagem dinâmica. * Notem que no src da tag img coloquei o arquivo img.php. Lembram-se de que eu disse que o img.php atuaria como uma imagem propriamente dita? De fato, atuará. ;) :D auth.php => Arquivo responsável por receber o código digitado e compará-lo com o armazenado na sessão<?php session_start(); require_once "class.img_auth.php"; ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="content-type" content="text/html; charset=iso-8859-1" /> <title>Autenticação</title> </head> <body> <?php $Im = new ImgAuth(); if ($Im->CodeCompare($_POST['code'])) { echo "<h2 style=\"color: blue;\">Código correto!</h2>"; session_destroy(); } else { echo "<h2 style=\"color: red;\">Erro. Código incorreto!</h2>"; session_destroy(); } ?> </body> </html>No mesmo diretório em que ficarão esses arquivos, crie um diretório para armazenar as fontes True Type e divirta-se. :D
Deixarei um exemplo completo em anexo.
Download do arquivo
Abraços,
Beraldo
Editado por BeraldoAdição do link para baixar o sistema completo
Link para o comentário
Compartilhar em outros sites
4 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.