+3

Gerando campo Captcha para validar formulários

criado por Everton Salomão em 28/05/2009 9:12am
Nesse artigo pretendo demostrar uma forma fácil de fazer um captcha e acabar com os spams em formulários.

Primeiro, precisamos gerar uma chave aleatória que o usuário vai precisar digitar para validar.

<?php
function key($t)
{ 
    $car = "1234567890abcdefghijklmnopqrstuvwxyz";
    for ($i = 0; $i < $t; $i++) {
        $key .= $car{rand(0, strlen($car) - 1)};
    } 
    return $key;
}
?>

Essa função gera uma chave com caracteres aleatórios que estão dentro da variável $car com o tamanho informado na variável $t.

Depois vamos gerar a imagem que vai aparecer para o usuário.

<?php
function criaimagem()
{
    global $key; 

    $key = key(8);
    $img = ImageCreate(130,20);
    $fundo = ImageColorAllocate($img,0,0,0);
    $texto = ImageColorAllocate($img,255,255,255);
    ImageString($img,5,23,2,$key,$texto); 
    ImageJpeg($img,"captcha.jpg");
}
criaimagem();
?>

Essa função gera uma imagem de 130x20 com a chave que foi criada pela função anterior. Veja que a função key é chamada com o valor 8, ou seja a chave gerada será de 8 caracteres, esse valor pode ser alterado conforme sua preferencia. A imagem será criada com Fundo preto e o texto em branco, conforme as variáveis fundo e texto. E finalmente a imagem é salva com o nome de captcha.jpg. E na última linha a função é chamada para gerar a imagem.

Agora vamos criar o JavaScript que vai validar o campo do captcha.

function ValidaForm()
{
    captcha = "<?php echo $key; ?>";
    if (document.forms[0].captcha.value != captcha) {
        alert("Código de verificação incorreto, favor tentar novamente");
        return false;
    }
}

Esse script em JS pega o valor da variavel key que foi criada junto com a imagem e armazena na variavel captcha, e depois compara com o texto que foi escrito no formulário que o usuário preenche, se estiver correto ele prossegue normalmente, se estiver diferente ele alerta o usuário e para o processo de envio do formulário.

Agora com todos as funções prontas, vamos criar um formulário para demonstrar como o captcha deverá ser incluido em seu formulário.

<form id="form1" name="form1" method="post" action="#" onsubmit="return ValidaForm()">

  Digite o código ao lado: 
  <input type="text" name="captcha" id="captcha">
  <img src="chave.jpg" border=0 />
  
  <input type="submit" value="Validar">

</form>

Esse é um formulário simples com apenas um campo para ser escrito o captcha e a imagem sendo exibida ao lado. Na hora do envio ele chama o JS e verifica se o código digitado esta correto.

Espero ter ajudado o pessoal e fazer diminuir esse tipo de envio atravéss de nossos formulários.

Everton Salomão
http://www.qubedesign.com.br

Comentários:

Mostrando 1 - 7 de 7 comentários
Ricardo disse:
excelente post....
Tão de parabéns Everton e Zariel...

Funcionou perfeitamente...quebrou um galhão pra mim !!!
18/06/2010 8:36am (~6 anos atrás)

Everton,
Achei muito interessante e resolvi fazer alguns testes para um projeto. Alguma coisinhas não davam certo em função das versões mas fiz as adaptações que algunsjá sugeriram acima e acabou funcionando.

Só que tem um problema que achei solução parcial. É o fato da imagem anterior ficar em cache no IE. Ao sair da página de cadastro (que eu uso o captcha) e depois voltar novamente (pelo link do cadastro, por exemplo) a imagem gerada anteriormente ainda fica lá. Se eu dou um reload funciona normal, mas sem reload nada feito no IE. O cache dele atrapalha essas coisas.

Eu fiz um esquema para apagar a imagem ao carregar a página, o que funcionou no Firefox, mas no bendito IE não funciona.

Então como solução eu resolvi fazer o seguinte.
- Useri o variável $key como sendo o nome da imagem, então toda vez que gerar uma imagem ela será única, dando driblada no IE.

Daí para exibir a imagem basta usar <img src"<? echo "$key.jpg"?>">
Como vai virando uma zona, cheio de imagens do captcha eu mandei criar as inagens em um sub-diretório e tb fiz uma rotina para apagar as velhas (apaga tudo, menos a útima gerada)

Queria saber se você ou os colegas teriam alguma solução mais elegante para driblar oproblema do cache do IE.

Obs:
- Tentei intrução em javascript pra trabalhar o header e o cache, mas não deu.
- META TAG também não deu certo.

Abraço
Marcos
15/02/2010 2:56am (~6 anos atrás)

Tem como criar um link para atualizar a imagem em javascript, sem precisar atualizar a pagina.

Abçs
13/09/2009 7:21pm (~7 anos atrás)

Zariel Larsen disse:
Olá, sou novo aqui...mais já acompanho os artigos desta comunidades há anos

E gostei muito de seu artigo, que possibilita personalizarmos nosso proprio captcha, está de parabéns exceto por dois erros gerado em meu exemplo, em que tive modificar deste seu:

1º a função key() de seu exemplo estava dando um conflito com a função key do meu php, uso php 5, então troquei o nome dessa função no meu exempo por chave() e não deu mais erro

2º a imagem captcha em meu exemplo não aparecia, pois a imagem gerada em seu exemplo é gerada como captcha.jpg, e no formulário estava como chave.jpg...então foi só trocar src da img no formulario pelo a da função criaimagem, que funcionou normalmente

excetos essas modificações, aqui funcionou perfeitamente

Falow!!!
10/06/2009 11:23am (~7 anos atrás)

Everton,

Ah sim, realmente nesse caso nao existe outra opcao :)

--Joao
29/05/2009 10:47am (~7 anos atrás)

João,

Sim existe os captchas por ai, inclusive o recaptcha é muito bom e já usei em alguns projetos meus. Mas a grande vantagem de vc ter um captcha próprio é a personalização. Percebi isso quando usei o reCaptcha em um cliente e ele não gostou, queria algo do jeito dele. Ai a solução foi fazer um.

Everton
29/05/2009 7:15am (~7 anos atrás)

Everton,

Bom conteudo no artigo, e acho importante disseminar mais informações sobre como criar esse tipo de sistemas para evitar/lutar contra spam.

Só acho que não é necessário criar um sistema novo, já que já existem serviços gratuitos online que podem ser usados para colocar um campo CAPTCHA em sites. Estamos usando o Recaptcha.net, e funciona muito bem e é bem simples de implementar.

--Joao
28/05/2009 10:56pm (~7 anos atrás)

Novo Comentário:

(Você pode usar tags como <b>, <i> ou <code>. URLs serão convertidas para links automaticamente.)