Django es el entorno de desarrollo web para perfeccionistas con límites de tiempo

Evitar SPAM en formularios con magicforms

¿Quieres evitar el spam en tus formularios sin tener que utilizar captchas ni tener que recurrir a servicios de terceros como Askimet? Entonces magicforms probablemente sea lo que estés buscando. Creado por fíam (también creador de byNotes) estas dos clases que heredan de django.forms.Form y django.forms.ModelForm respectivamente te ayudan a engañar a los spambots y tener unos formularios limpos de spam.

¿Cómo se consigue? Utilizando un campo con estilo display:none para que no sea mostrado en el navegador (que hace de honeypot). Este campo no aparece en el navegador pero los spambots sí lo ven y tratarán de rellenarlo. El campo permite una longitud máxima de cero, por lo que el formulario no validará correctamente si este campo contiene alguna información. De esta forma se evita que se acepte un formulario rellenado por un spambot.

El otro método adicional añade un campo hidden que contiene un token generado a partir de la IP del visitante y el timestamp actual encriptados utilzando el setting SECTRET_KEY de tu proyecto como llave del cifrado. De esta forma al validar el formulario se descifra el valor del campo y se compara la IP del visitante con la almacenada anteriormente para verificar que son las mismas. Tras esto se compara el timestamp actual con el almacenado para que el formulario no valide correctamente si se ha enviado en menos de 5 segundos desde el timestamp inicial (demasiado rápido para ser un humano quien esté enviándolo) o más de 1 hora después por si el spambot reutiliza el token en el futuro.

Utilizarlo es realmente sencillo: En lugar de heredar de Form y ModelForm tus formularios deberán heredar de MagicForm y MagicModelForm. A la hora de utilizarlos en tus vistas al crear un objeto formulario deberás pasarle como argumentos request.META['REMOTE_ADDR'] (la IP del visitante) y un identificador único (por ejemplo el id del modelo asociado al formulario) además de los argumentos que quieras para el formulario. Suponiendo que tuvieramos un modelo Comentario como el siguiente:

from django.db import models

class Entrada(models.Model):
    # ...

class Comentario(models.Model):
    entrada = models.ForeignKey(Entrada)
    texto = models.TextField()

El código para nuestro formuario sería:

from models import Comentario
from magicforms import MagicModelForm

class ComentarioForm(MagicModelForm):
    class Meta:
        model = Comentario

Y nuestra vista para añadir un comentario, suponiendo que le pasamos el id de la entrada por la URL sería:

from django.shortcuts import get_object_or_404

def add_comentario(request, entrada_id):
    entrada = get_object_or_404(Entrada, id=entrada_id)
    formulario = ComentarioForm(request.META['REMOTE_ADDR'], entrada.id)
    if request.method == 'POST':
        formulario = ComentarioForm(request.META['REMOTE_ADDR'], entrada.id, request.POST)
    # ...

Descarga magicforms.py para Django. Puedes leer la entrada original en inglés sobre magicforms en el blog de fíam.

Publicado por Antonio Melé el Domingo 14 de Diciembre de 2008 Compártelo: Facebook: Twitter: | Categorías: forms, spam

Entradas similares

Formularios con Django sin SPAM

¿Quieres luchar contra el SPAM en tus formularios sin tener que modificarlos? Una forma sencilla de evitar gran parte del SPAM automático son los ...


Utilizar un formulario para modificar dos modelos

Actualización/Update: Zack translated this post into english and it is available here.

A veces tenemos que modificar información relativa a dos o más ...


 
Probando los sabores de localflavor

Django incluye la aplicación django.contrib.localflavor que agrupa campos de formulario y widgets específicos para distintos países. Vamos a ver lo que podemos ...


Modificar la QuerySet de un ModelChoiceField dinámicamente

El campo de formulario ModelChoiceField sirve para permitir la selección de un elemento entre los objetos resultantes de una QuerySet. La QuerySet inicial puede ...


 
 

4 comentarios:

El Lunes 15 de Diciembre de 2008 Alberto García Hierro dijo:

Gracias por hacer un artículo en castellano sobre magicforms ;).

El Martes 16 de Diciembre de 2008 Antonio Melé dijo:

Alberto, ¡gracias a ti por esos forms tan mágicos!

El Jueves 18 de Diciembre de 2008 guillem dijo:

Hace años que utilizo el mismo método antispam: si aparece la palabra http no acepta el comentario. No he tenido ni un solo mensaje de spam en el blog desde que lo introduje.

El Viernes 19 de Diciembre de 2008 Antonio Melé dijo:

guillem, es una forma simple y eficaz pero por otro lado impide que quien comenta indique algún enlace relacionado con el post. Aún así puede que en ciertos casos sea una opción adecuada.

Escribe un comentario: