Ir para conteúdo
Fórum Script Brasil
  • 0

Classe Autenticação Por Imagem


Beraldo

Pergunta

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
<?php

require_once "class.img_auth.php";

$Im = new ImgAuth();
$Im->ImgHeader();
$Im->SetImgCode();
$Im->CreateImg();
?>
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
<?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 Beraldo
Adiçã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

  • 0

Olá beraldo !!!

tive um problema com sua classe

por exemplo:

se eu deixo o campo em branco, e envio ele retorna a mensagem " Codigo correto"。。

já se eu digito o código correto, ele retorna " Codigo incorreto ".

e em ambos os casos ele ainda mostra erro ao finalizar a session..

Warning: session_destroy() [function.session-destroy]: Trying to destroy uninitialized session in \htdocs\img\auth.php on line 17
e do geito que baixei eu rodei no servidor web... tentei modificar o arquivo auth.php para:
<?php
require_once "class.img_auth.php";
?>

if ($code== $_SESSION['auth_code']) { echo"Código OK"; } else { echo"Código errado"; }

mas o erro é o mesmo...

testei em localhost, e em meu host particular, ambos com PHP5.

Desde já obrigado.

Link para o comentário
Compartilhar em outros sites

  • 0

Obrigado Beraldo.

agora tenho uma pergunta...

na sua classe está lá:

if (!isset($_SESSION))
        {
            session_start();
        }
        
        $_SESSION['auth_code'] = $this->code;
        
    }

o qual você até comentou que inicia a session se não tiver...

se no arquivo auth.php

que antes estava sem o session_start

não era para iniciar a session ?

foi só uma duvida que me surgiu !!!

mas obrigado pela sua resposta !!!

Link para o comentário
Compartilhar em outros sites

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.

Visitante
Responder esta pergunta...

×   Você colou conteúdo com formatação.   Remover formatação

  Apenas 75 emoticons são permitidos.

×   Seu link foi incorporado automaticamente.   Exibir como um link em vez disso

×   Seu conteúdo anterior foi restaurado.   Limpar Editor

×   Você não pode colar imagens diretamente. Carregar ou inserir imagens do URL.



  • Estatísticas dos Fóruns

    • Tópicos
      152,1k
    • Posts
      651,8k
×
×
  • Criar Novo...