Kyrux
Voltar

Captcha (core/security/captcha)

Desafio visual simples (código numérico distorcido, renderizado como PNG) para formulários públicos — sem depender de nenhum serviço externo (Google reCAPTCHA, hCaptcha, etc). Zero configuração de conta, zero chave de API, zero chamada de rede para o navegador do visitante bloquear ou atrasar.

Uso pronto — captcha.Store

import "kyrux/core/security/captcha"

captchaStore := captcha.NewStore(fw.Sessions)

router.Path("GET", "/captcha/image", captchaStore.ImageHandler(), "captcha_image"),

// no handler de POST do formulário:
if !captchaStore.Verify(ctx, ctx.Request.FormValue("captcha_answer")) {
    // código incorreto — mostre erro e não processe o formulário
}

No template:

<img src="{{ url "captcha_image" }}" alt="Código de verificação" id="captchaImg">
<input type="text" name="captcha_answer" maxlength="5" inputmode="numeric" required>

ImageHandler gera um código novo a cada requisição (útil para um "gerar outro" no front — troque o src da imagem com um cache-buster, ex: ?t=Date.now()) e guarda na sessão do visitante, substituindo o anterior. Verify confere a resposta contra o código da sessão e o consome (uso único) independente do resultado — sempre precisa de uma imagem nova para uma nova tentativa.

Primitivas de baixo nível

Para guardar o código em outro lugar que não sessão (ex: banco, num fluxo sem cookie):

code, err := captcha.New()      // código aleatório de captcha.CodeLength dígitos
png, err := captcha.PNG(code)   // imagem PNG distorcida do código

Como funciona a imagem

Fonte bitmap 5x7 própria (só dígitos 0-9, sem ambiguidade visual tipo 0/O ou 1/I/l), desenhada com image/image/png da stdlib — sem golang.org/x/image nem nenhuma outra dependência de terceiros. Ruído de fundo (linhas e pontos aleatórios) e leve inclinação por caractere dificultam OCR automatizado simples.