ervin11/honeypot-bundle

HoneypotBundle 是一个简单的方法,用于为您的 symfony 联系表单实现蜜罐系统,以阻止来自垃圾邮件机器人的垃圾邮件。

安装: 6

依赖关系: 0

建议者: 0

安全: 0

星星: 1

分支: 0

类型:symfony-bundle

1.1 2022-06-03 15:03 UTC

This package is auto-updated.

Last update: 2024-09-30 02:02:52 UTC


README

HoneypotBundle 是一个简单的方法,用于为您的 symfony 联系表单实现蜜罐系统,以阻止来自垃圾邮件机器人的垃圾邮件。

使用以下命令安装包:

composer require ervin11/honeypot-bundle

然后...就完成了!如果您不使用 Symfony Flex,您还需要在您的 AppKernel.php 文件中启用 Ervin11\HoneypotBundle\HoneypotBundle。

文件

此包提供了一个

  • HoneypotTrait,它提供了一个存储在数据库中的电子邮件字段和一个仅用于垃圾邮件验证的 fakeEmail 字段。
# Ervin11\HoneypotBundle\Traits;

trait HoneypotableTrait {

    /**
     * @ORM\Column(type="string", length=255)
     */
    protected ?string $email;

    protected string $fakeEmail;
    
    // ...
}
  • HoneypotType,您可以使用它来添加 `email 和一个隐藏的 fakeEmail 表单字段。该 fakeEmail 字段具有一个回调验证,它会调用 manageSpam 函数,在其中执行垃圾邮件验证。
# Ervin11\HoneypotBundle\Types;

class HoneypotType extends AbstractType
{
    public const CODE = 'SPAM';
    
    // ...
    
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('email', EmailType::class,
                [
                    'required' => true,
                    'constraints' => [
                        new Assert\NotNull(),
                        new Assert\Email(null, "The email '{{ value }}' is not a valid email.", "strict")
                    ]
                ])
            ->add('fakeEmail', EmailType::class,
                [
                    'label_attr' => [
                        'style' => 'font-size: 0;'
                    ],
                    'attr' => [
                        'style' => 'height: 0; width: 0; margin: 0; padding: 0; text-decoration: none; border: none;'
                    ],
                    'row_attr' => [
                        'style' => 'margin: 0 !important; height: 0; width: 0; color:transparent;'
                    ],
                    'constraints' => new Assert\Callback([$this, 'manageSpam']),
                    'required' => false,
                ]);
    }

    public function manageSpam($data, ExecutionContextInterface $context): void
    {
        $form = $context->getRoot();
        $fakeEmail = ($form->get("honeypot"))->get('fakeEmail')->getData();

        /** @var Request $request */
        $request = $this->requestStack->getCurrentRequest();

        $ip = $request->getClientIp();

        if ($fakeEmail) {

            if ($this->logger) {
                $this->logger->alert("Spam tried with $fakeEmail from $ip");
            }

            $context
                ->buildViolation("Spam tried with $fakeEmail from $ip")
                ->setCode(self::CODE)
                ->setParameters(['email' => $fakeEmail, 'ip' => $ip])
                ->addViolation();
        }
    }
    
    // ...
}

用法

首先,您必须在包含联系表单数据的实体类中添加 `use HoneypotableTrait`。

class Message
{
    use HoneypotableTrait;

    /**
     * @ORM\Id()
     * @ORM\GeneratedValue()
     * @ORM\Column(type="integer")
     */
    private int $id;
    
    // ...
}

然后,您需要创建一个新的迁移,并使用以下命令运行它:

php bin/console make:mig && php bin/console d:m:m -n

一旦迁移完成,您就可以在您的联系表单中添加 HoneypotType 字段

# src/Form/MessageType

class MessageType extends AbstractType
{
    // ...
    
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('firstname', TextType::class)
            ->add('lastname', TextType::class)
            ->add('honeypot', HoneypotType::class)
            ->add('save', SubmitType::class, ['label' => 'Send Message']);
    }
    
    // ...
}

然后,您可以在包含联系表单字段的 twig 模板中获取蜜罐字段,如下所示:

// ...

{% block body %}

{{ form_start(form) }}

// ...

{{ form_row(form.honeypot.email) }}
{{ form_row(form.honeypot.fakeEmail) }}

// ...

{{ form_end(form) }}

{% endblock %}

在表单提交时,如果 HoneypotType 的 `manageSpam 函数检测到垃圾邮件,它将在表单的隐藏 fakeEmail 字段中构建和添加违规,此时 $form->isValid() 将返回 false。

此违规包含一个您需要时可以使用的参数数组。

[
    'email' => 'honeypot@test.com', 
    'ip' => '127.0.0.1'
]
$errors = $form->getErrors(true);
$spamDetected = $errors->findByCodes(HoneypotType::CODE);

if (count($spamDetected) !== 0) {
    $spamData = $spamDetected->current()->getMessageParameters();
}

订阅者

当 HoneypotType 的 manageSpam 函数检测到垃圾邮件时,它还会分派一个包含垃圾邮件发送者电子邮件和 IP 地址的 `HoneypotSpamDetectedEvent`。您可以通过创建订阅者来监听它。

<?php

namespace App\EventSubscriber;

use Ervin11\HoneypotBundle\Event\HoneypotSpamDetectedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class HoneypotSpamSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            HoneypotSpamDetectedEvent::NAME => 'onSpamDetected',
        ];
    }

    public function onSpamDetected(HoneypotSpamDetectedEvent $event)
    {
      // ... Do something
    }
}

日志记录

如果您的开发模式中有一个 monolog 默认主通道,它将在 /var/log/dev.log 中记录电子邮件和 IP 地址。