All Projects → karser → Karserrecaptcha3bundle

karser / Karserrecaptcha3bundle

Licence: mit
Google ReCAPTCHA v3 for Symfony

Projects that are alternatives of or similar to Karserrecaptcha3bundle

PRRecaptchaBundle
Recaptcha v3 bundle for Symfony
Stars: ✭ 14 (-73.08%)
Mutual labels:  recaptcha, symfony-bundle
Beelabrecaptcha2bundle
💻 Symfony bundle for Google Recaptcha2
Stars: ✭ 47 (-9.62%)
Mutual labels:  symfony-bundle, recaptcha
Jmsserializerbundlebridge
[READ ONLY] Symfony bundle for using JMSSerializer as message serializer for SimpleBus/Asynchronous
Stars: ✭ 10 (-80.77%)
Mutual labels:  symfony-bundle
Drf Recaptcha
Django REST framework reCAPTCHA
Stars: ✭ 47 (-9.62%)
Mutual labels:  recaptcha
Puppeteer Sharp Extra
Plugin framework for PuppeteerSharp
Stars: ✭ 39 (-25%)
Mutual labels:  recaptcha
Anticaptchaff
Firefox Extension to automatically solve and bypass reCaptcha
Stars: ✭ 20 (-61.54%)
Mutual labels:  recaptcha
Enqueue Elastica Bundle
The bundle extends functionality of FOSElasticaBundle. Improves performance of fos:elastica:populate command
Stars: ✭ 40 (-23.08%)
Mutual labels:  symfony-bundle
Asynchronous Bundle
[READ ONLY] Symfony bundle for using SimpleBus/Asynchronous
Stars: ✭ 22 (-57.69%)
Mutual labels:  symfony-bundle
Oneupaclbundle
The missing link between Symfonys Acl implementation and your application.
Stars: ✭ 48 (-7.69%)
Mutual labels:  symfony-bundle
Isometriksspambundle
Symfony3 Form Spam Protection
Stars: ✭ 38 (-26.92%)
Mutual labels:  symfony-bundle
Seo Bundle
A SEO Solution for duplicate contents, page titles, etc.
Stars: ✭ 45 (-13.46%)
Mutual labels:  symfony-bundle
Sncredisbundle
A Redis bundle for Symfony supporting Predis and PhpRedis
Stars: ✭ 980 (+1784.62%)
Mutual labels:  symfony-bundle
Webfactoryicutranslationbundle
Enables ICU message formatting for translations in Symfony applications.
Stars: ✭ 27 (-48.08%)
Mutual labels:  symfony-bundle
Lexikpayboxbundle
LexikPayboxBundle eases the implementation of the Paybox payment system
Stars: ✭ 42 (-19.23%)
Mutual labels:  symfony-bundle
Recaptcha Rs
Verify recaptcha responses
Stars: ✭ 10 (-80.77%)
Mutual labels:  recaptcha
Symfony Crawler Bundle
Implements the crawler package into Symfony
Stars: ✭ 8 (-84.62%)
Mutual labels:  symfony-bundle
Social Post Bundle
Symfony bundle to publish status updates on Facebook, LinkedIn and Twitter.
Stars: ✭ 35 (-32.69%)
Mutual labels:  symfony-bundle
Captchavel
Integrate reCAPTCHA into your Laravel app better than the Big G itself!
Stars: ✭ 40 (-23.08%)
Mutual labels:  recaptcha
Recaptcha Go
Validate Google reCAPTCHA v2 & v3 form submission package in golang
Stars: ✭ 49 (-5.77%)
Mutual labels:  recaptcha
Knpsnappybundle
Easily create PDF and images in Symfony by converting html using webkit
Stars: ✭ 1,038 (+1896.15%)
Mutual labels:  symfony-bundle

KarserRecaptcha3Bundle

Build Status Scrutinizer Code Quality Code Coverage Total Downloads

reCAPTCHA v3 returns a score for each request without user friction. The score is based on interactions with your site (1.0 is very likely a good interaction, 0.0 is very likely a bot) and enables you to take an appropriate action for your site. Register reCAPTCHA v3 keys here.

image

Installation

With composer, require:

composer require karser/karser-recaptcha3-bundle

You can quickly configure this bundle by using symfony/flex:

  • answer no for google/recaptcha
  • answer yes for karser/karser-recaptcha3-bundle image

Configuration without symfony/flex:

1. Register the bundle

Symfony 4/5 Version :
Register bundle into config/bundles.php:

return [
    //...
    Karser\Recaptcha3Bundle\KarserRecaptcha3Bundle::class => ['all' => true],
];

Symfony 3 Version:
Register bundle into app/AppKernel.php:

public function registerBundles()
{
    return array(
        // ...
        new Karser\Recaptcha3Bundle\KarserRecaptcha3Bundle(),
    );
}

2. Add configuration files

# config/packages/karser_recaptcha3.yaml (or app/config/config.yml if using Symfony3)
karser_recaptcha3:
    site_key: '%env(RECAPTCHA3_KEY)%'
    secret_key: '%env(RECAPTCHA3_SECRET)%'
    score_threshold: 0.5

Add your site key and secret to your .env file:

###> karser/recaptcha3-bundle ###
RECAPTCHA3_KEY=my_site_key
RECAPTCHA3_SECRET=my_secret
###< karser/recaptcha3-bundle ###

Usage

How to integrate re-captcha in Symfony form:

<?php

use Karser\Recaptcha3Bundle\Form\Recaptcha3Type;
use Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3;

class TaskType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('captcha', Recaptcha3Type::class, [
            'constraints' => new Recaptcha3(),
            'action_name' => 'homepage',
            'script_nonce_csp' => $nonceCSP,
        ]);
    }
}

Notes:

  • The action_name parameter is reCAPTCHA v3 action which identifies the submission of this particular form in the Google reCAPTCHA dashboard, and confirming it is as expected in the backend is a recommended extra security step.
  • The script_nonce_csp parameter is optional. You must use the same nonce as in your Content-Security Policy header.

How to get the ReCaptcha score:

Inject the Recaptcha3Validator and call getLastResponse()->getScore() after the form was submitted:

<?php

use Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3Validator;

class TaskController extends AbstractController
{
    public function new(Request $request, Recaptcha3Validator $recaptcha3Validator): Response
    {
        //...
        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            //...
            $score = $recaptcha3Validator->getLastResponse()->getScore();
            //...
        }
        //...
    }
}

How to integrate re-captcha in API method:

The idea is to require the frontend to submit the captcha token, so it will be validated on server side.

First you need to add the captcha field to your transport entity:

<?php

namespace App\Dto;

final class UserSignupRequest
{
    /** @var string|null */
    public $email;

    /** @var string|null */
    public $captcha;
}

And to add the validation constraint:

#config/validator/validation.yaml
App\Dto\UserSignupRequest:
    properties:
        email:
            - NotBlank: ~
            - Email: { mode: strict }
        captcha:
            - Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3: ~

On frontend part you need to submit the captcha token along with email. You can obtain the captcha token either on page load or on form submit.

<script src="https://www.google.com/recaptcha/api.js?render=<siteKey>"></script>

<script>
const siteKey = '*****************-**-******-******';

//either on page load
grecaptcha.ready(function() {
    grecaptcha.execute(siteKey, {
        action: 'homepage'
    }).then(function(token) {
        //the token will be sent on form submit
        $('[name="captcha"]').val(token);
        //keep in mind that token expires in 120 seconds so it's better to add setTimeout.
    });
});

//or on form post:
grecaptcha.ready(function() {
    grecaptcha.execute(siteKey, {
        action: 'homepage'
    }).then(function(token) {
        //submit the form
        return http.post(url, {email, captcha: token});
    });
});
</script>

How to show errors from the captcha's response

Just add the {{ errorCodes }} variable to the message template:

$formBuilder->add('captcha', Recaptcha3Type::class, [
    'constraints' => new Recaptcha3(['message' => 'There were problems with your captcha. Please try again or contact with support and provide following code(s): {{ errorCodes }}']),
])

How to deal with functional and e2e testing:

Recaptcha won't allow you to test your app efficiently unless you disable it for the environment you are testing against.

# app/config/config.yml (or config/packages/karser_recaptcha3.yaml if using Symfony4)
karser_recaptcha3:
    enabled: '%env(bool:RECAPTCHA3_ENABLED)%'
#.env.test or an environment variable
RECAPTCHA3_ENABLED=0

How to set the threshold from PHP dynamically rather from the .yaml config or .env?

You should inject @karser_recaptcha3.google.recaptcha in your service and call setScoreThreshold method.

#services.yaml
App\Services\YourService:
    arguments: ['@karser_recaptcha3.google.recaptcha']
#App/Services/YourService.php

use ReCaptcha\ReCaptcha;

class YourService {
    private $reCaptcha;

    public function __construct(ReCaptcha $reCaptcha) {
        $this->reCaptcha = $reCaptcha;
    }

    public function yourMethod() {
        $this->reCaptcha->setScoreThreshold(0.7);
    }
}

How to resolve IP propertly when behind Cloudflare:

From the Cloudflare docs: To provide the client (visitor) IP address for every request to the origin, Cloudflare adds the CF-Connecting-IP header.

"CF-Connecting-IP: A.B.C.D"

So you can implement custom IP resolver which attempts to read the CF-Connecting-IP header or fallbacks with the internal IP resolver:

<?php declare(strict_types=1);

namespace App\Service;

use Karser\Recaptcha3Bundle\Services\IpResolverInterface;
use Symfony\Component\HttpFoundation\RequestStack;

class CloudflareIpResolver implements IpResolverInterface
{
    /** @var IpResolverInterface */
    private $decorated;

    /** @var RequestStack */
    private $requestStack;

    public function __construct(IpResolverInterface $decorated, RequestStack $requestStack)
    {
        $this->decorated = $decorated;
        $this->requestStack = $requestStack;
    }

    public function resolveIp(): ?string
    {
        return $this->doResolveIp() ?? $this->decorated->resolveIp();
    }

    private function doResolveIp(): ?string
    {
        $request = $this->requestStack->getCurrentRequest();
        if ($request === null) {
            return null;
        }
        return $request->server->get('HTTP_CF_CONNECTING_IP');
    }
}

Here is the service declaration. It decorates the internal resolver:

#services.yaml
services:
    App\Service\CloudflareIpResolver:
        decorates: 'karser_recaptcha3.ip_resolver'
        arguments:
            $decorated: '@App\Service\CloudflareIpResolver.inner'
            $requestStack: '@request_stack'

Troubleshooting checklist

Make sure you setup recaptcha key/secret of version 3.

Also, make sure you added the domain you use in the recaptcha settings. Usually dev domain differs from the production one, so better to double check. image

Make sure you are seeing this in the html of your rendered form

<input type="hidden" id="form_captcha" name="form[captcha]" /><script>
    var recaptchaCallback_form_captcha = function() {
    grecaptcha.execute('<YOUR-RECAPTCHA-KEY>', {action: 'landing'}).then(function(token) {
    document.getElementById('form_captcha').value = token;
    });
    };
    </script><script src="https://www.google.com/recaptcha/api.js?render=<YOUR-RECAPTCHA-KEY>&onload=recaptchaCallback_form_captcha" async defer></script> 
</form>

Make sure you don't have javascript errors in the browser console

Testing

composer update
vendor/bin/phpunit
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].