This packages integrates ALTCHA, a privacy-friendly Captcha alternative, with Symfony forms.
Simply add an AltchaType field to your form and this package will automatically check the challenge issue.
ALTCHA uses a proof-of-work mechanism to protect your website, APIs, and online services from spam and unwanted content.
Unlike other solutions, ALTCHA is free, open-source and self-hosted, does not use cookies nor fingerprinting, does not track users, and is fully compliant with GDPR.
Say goodbye to tedious puzzle-solving and improve your website's UX by integrating a fully automated proof-of-work mechanism.
- Symfony 6.4 | 7.4 | 8.0+
- PHP 8.2+
- Webpack | Asset Mapper | Twig
You can install the package via Composer:
composer require tito10047/altcha-bundleAdd bundle into config/bundles.php file:
Tito10047\AltchaBundle\AltchaBundle::class => ['all' => true]Add a config file:
config/packages/altcha.yaml
altcha:
enable: true
hmacSignature: '%env(APP_SECRET)%'
hmacAlgorithm: 'SHA-256'
cost: 5000
counter_min: 5000
counter_max: 10000
timeout: 30.0
floating: true
overlay: false
use_stimulus: false
include_script: true
hide_logo: false
hide_footer: false
when@test:
altcha:
enable: falseImport bundle routes:
altcha:
resource: '@AltchaBundle/config/routes.yml'
type: yamlIf your application restricts access globally using a rule like:
access_control:
- { path: ^/, roles: ROLE_USER }Then the Altcha challenge endpoint (/altcha/challenge) will also be protected by default.
To allow it to be publicly accessible (as intended for the challenge mechanism to work), you must explicitly add the following rule before the global one:
access_control:
- { path: ^/altcha/challenge, roles: PUBLIC_ACCESS }
- { path: ^/, roles: ROLE_USER }This ensures that the challenge endpoint is reachable by unauthenticated users, while keeping the rest of your app secure.
Create a form type and insert an AltchaType to add the captcha:
<?php
namespace App\Form;
use App\Entity\Contact;
use Tito10047\AltchaBundle\Type\AltchaType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class ContactType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('name', TextType::class, ['label' => false, 'attr' => ['placeholder' => 'name']])
->add('message', TextareaType::class, ['label' => false, 'attr' => ['placeholder' => 'message']])
->add('security', AltchaType::class, [
'label' => false,
'floating' => true,
'hide_logo' => false,
'hide_footer' => false,
])
->add('submit', SubmitType::class)
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => Contact::class,
]);
}
}//webpack.config.js
module.exports = Encore.getWebpackConfig();
module.exports.resolve.alias["altcha/dist/i18n/all.js"]='altcha/i18n';#config/packages/altcha.yaml
altcha:
use_stimulus: true
include_script: falseThere is only one option need to be changed to work with or UX Live component.
altcha:
use_stimulus: true
floating: false
include_script: falseConfigure the package by providing your sentinel instance endpoint and your API key:
altcha:
sentinel:
base_url: 'http://localhost:8080'
api_key: 'key_xxxxxxxxxxxx'Activating this configuration will have the effect to use the sentinel server to generate a new challenge and for it's verification. If the sentinel instance is not reachable by the client or by the server, we will fallback on our local configuration.
Rate limiting prevents the same challenge token from being validated multiple times (replay attack protection). Requires symfony/rate-limiter:
composer require symfony/rate-limiterConfigure a rate limiter policy:
# config/packages/framework.yaml
framework:
rate_limiter:
altcha_challenge:
policy: 'fixed_window'
limit: 1
interval: '15 minutes'Reference the limiter service in the altcha config:
# config/packages/altcha.yaml
altcha:
hmacSignature: '%env(APP_SECRET)%'
rate_limiter: 'limiter.altcha_challenge'The challenge signature is used as the rate limiter key. With the configuration above, each unique challenge token can only be validated once per 15 minutes. If the limit is exceeded, the form will display: "Too many attempts. Please try again later."
If symfony/rate-limiter is not installed and rate_limiter is configured, the container build will throw a LogicException with a helpful message.
The MIT License (MIT). Please see License File for more information.