Giter Club home page Giter Club logo

karserrecaptcha3bundle's Introduction

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/6/7 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,
            'locale' => 'de',
        ]);
    }
}

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.
  • The locale parameter is optional. It defaults to English and controls the language on the reCaptcha widget.

How to use reCAPTCHA globally (meaning even in China):

Use 'www.recaptcha.net' host in your code when 'www.google.com' is not accessible.

# config/packages/karser_recaptcha3.yaml (or app/config/config.yml if using Symfony3)

karser_recaptcha3:
    host: 'www.recaptcha.net' # default is 'www.google.com'

How can I set the captcha language for different locales?

You can control the language in the small widget displayed by setting the locale in the options above.

To change the error messages, you should install the Symfony Translation component.

Then replace the validation text with the translation keys for the message and messageMissingValue options:

$builder->add('captcha', Recaptcha3Type::class, [
     'constraints' => new Recaptcha3 ([
         'message' => 'karser_recaptcha3.message',
         'messageMissingValue' => 'karser_recaptcha3.message_missing_value',
     ]),
]);

Add English, Spanish, or any other translation:

# translations/validators/validators.en.yaml
karser_recaptcha3.message: 'Your computer or network may be sending automated queries'
karser_recaptcha3.message_missing_value: 'The captcha value is missing'

# translations/validators/validators.es.yaml
karser_recaptcha3.message: 'Es posible que su computadora o red esté enviando consultas automatizadas'
karser_recaptcha3.message_missing_value: 'Falta el valor de captcha'

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'

Symfony HttpClient integration

If you have a dependency on symfony/http-client in your application then it will be automatically wired to use via RequestMethod/SymfonyHttpClient.

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

karserrecaptcha3bundle's People

Contributors

chris53897 avatar chris8934 avatar jimihay avatar juan-carrera-stdcore avatar karser avatar mpoiriert avatar mrunkel avatar norkunas avatar pfcloutier-druide avatar poveu avatar prometee avatar romanapunts avatar uestla avatar ustinovv avatar yoshz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

karserrecaptcha3bundle's Issues

Getting the score?

Thanks for writing this bundle, it's working flawlessly!

I would like to store the score with our form submissions, so I can verify that we've picked a good score_threshold.

I thought that by mapping the form field I would get the details, but it returns a single long string.

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

# Gives
captcha = "03AGdBq27LZb9CZbMtrxPvl4JiscE5B...lots more...9I6j-5XzJS8"

Is it possible to retrieve the CAPTCHA check details?

Token expiration on form page refresh

Hello,

When I submit the form and then refresh the page (so, the browser resend the form), I got a symfony form error.

This is the errorCodes from Google:
"There were problems with your captcha. Please try again or contact with support and provide following code(s): "The response is no longer valid: either is too old or has been used previously; Score threshold not met"

Is it normal ?
Is it possible to allow users to resend the form with captcha recheck ?

Api key not loaded properly from .env file

I am trying to integrate captcha in symfony 4 form.
Steps taken:

  1. composer require karser/karser-recaptcha3-bundle
  2. Register the bundle
    Register bundle into config/bundles.php:
return [
    //...
    Karser\Recaptcha3Bundle\KarserRecaptcha3Bundle::class => ['all' => true],
];
  1. 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
  1. Add site key to .env file
###> karser/recaptcha3-bundle ###
RECAPTCHA3_KEY=actual_site_key
RECAPTCHA3_SECRET=actual_secret
###< karser/recaptcha3-bundle ###
  1. Finally added the form type to the form builder
<?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',
        ]);
        //$builder->add(...);
    }
}

Despite all this I am getting following error on my developer tools console:

`Uncaught (in promise) Error: Invalid site key or not loaded in api.js: my_site_key
`

Problem with vue.js

Hello,
we used your bundle in Symfony 4 project with vue.js and we get this error:

Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as <script>, as they will not be parsed.

This problem could be solved by adding type="application/javascript" into the <script> tag.

Currently we solved it by overriding template, but may be it make sense to add some specific parameter like for nonce attribute ?

Error SymfonyHttpClient::__construct(): Argument #1 ($httpClient) must be of type Symfony\Contracts\HttpClient\HttpClientInterface, null given

Hello !

I m trying to use this good bundle, however my constraint Recaptcha3 is not called (i think the problem is the validation group)

When i m trying to add a validation group like this :

$builder ->add('captcha', Recaptcha3Type::class, [
            'constraints' => new Recaptcha3(['groups' => ['sylius']]),
            'action_name' => 'register',
            'locale' => 'fr'
]);

I have this error after :
Karser\Recaptcha3Bundle\RequestMethod\SymfonyHttpClient::__construct(): Argument #1 ($httpClient) must be of type Symfony\Contracts\HttpClient\HttpClientInterface, null given, called in /home/chouettemauve/preprod/sylius/var/cache/dev/ContainerM8OPDeO/getKarserRecaptcha3_ValidatorService.php on line 29

Do you know what is the problem ?

Thank you :)

Get captcha value null on form submit

Hi I am getting captcha value null on form submit.

I can see the input field being set properly, token value is also updating in the input field but still getting captcha value null on form submit.

Thanks

Fail with PHP 7.4

Using version ^2.3 for beelab/recaptcha2-bundle
./composer.json has been updated
Loading composer repositories with package information
Updating dependencies (including require-dev)
Restricting packages listed in "symfony/symfony" to "5.0.*"
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - This package requires php 7.3.* but your HHVM version does not satisfy that requirement.


Installation failed, reverting ./composer.json to its original content.

JS error "Invalid side key"

I have implemented KarserRecaptcha3Bundle to my project. In browser console I kepp on getting error:

Error: Invalid site key or not loaded in api.js: _reCAPTCHA_site_key_

Site key was created in Google reCAPTCHA admin interface and copied to my configuration. Do you have any idea what goes wrong here?

Symfony 5 : Error: Unknown base64 encoding at char

Hello Karser,

I am using your Bundle v3 and followed the installation. I want to integrate the ReCaptcha on a basic contact form,

I install with flex and am on Symfony 5.1, fill in my ContactType file as it should, then also write the two JavaScript scripts in my layout,

All that remains is to fill in my secret key and my Captcha key,

Despite all this, my inspector gives me the following error Error: Unknown base64 encoding at char:
The submission works, but does not seem to involve the captcha, I think I am not using the bundle completely correctly, would you have an indication for me please ?

I share with you the status of my current code, thank you very much for your work !

Layout.html.twig

<script>
const recaptchaCallback_form_captcha = function() {
grecaptcha.execute('******************************', {action: 'landing'}).then(function(token) {
document.getElementById('form_captcha').value = token;
});
};
</script>

<script src="https://www.google.com/recaptcha/api.js?render=******************************&onload=recaptchaCallback_form_captcha" async defer></script>

ContactType.php

namespace App\Form;

use App\Entity\Contact;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Karser\Recaptcha3Bundle\Form\Recaptcha3Type;
use Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3;

class ContactType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('pseudo')
            ->add('email')
            ->add('subject')
            ->add('message', TextareaType::class)
            ->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 }}']),
                'action_name' => 'contact',
                // 'script_nonce_csp' => $nonceCSP,
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => Contact::class,
        ]);
    }
}

contact.html.twig

    {{ form_start(form, {'attr': {'id': 'form-captcha'}}) }}
        {{ form_errors(form) }}
        {{ form_widget(form) }}
        <div class="text-center">
            <button class="btn btn-primary col-2">{{ button_label|default('Send') }}</button>
        </div>
    {{ form_end(form) }}

Capcha script are not loading on form render

Hi!

After configuring the bundle and setting it in symfony form following the documentation (installation with symfony flex) the scrips required form loading captcha token aren't load on the form. We had try re-installing the bundle.

If you need extra information ask for it.

Thank you,

Symfony version: 5.4
Bundle version: 0.1.23

Wrong constraint message

Error message is set as an constant instead of being set the correct one depends on the captcha's response. This is why you always get "Your computer or network may be sending automated queries" and not the correct message.

List of little issues

Hello thanks for providing open source a bundle for Recaptcha3, this is really kind. I'm going to try to help with a list of some things that can be improved:

  • You should not retrieve HTTP_CF_CONNECTING_IP directly. I understand this is on your use case but you probably should have a custom request or an IP resolver. It should not be hardcoded inside the validator
  • enabled option of form type is useless (is not used and makes no sense)
  • It should exist a way to add it to other pages than forms (considering this practice highly improve the power of the captcha)
  • Unit tests are missing!

Composer require - Config issue

Seems to be a problem with last config changes ?
After executing composer require karser/karser-recaptcha3-bundle (and ignoring google/recaptcha script) I have the following error :

  The child node "site_key" at path "karser_recaptcha3" must be configured.  

And then composer.json is reverted.

And the weird thing is that even if I preconfigure the karser_recaptcha3 params I still have the error !

Any idea ?

Using Symfony 4.4, composer 1.9.1, php 7.1.28

How do you verify the invisible reCAPTCHA is working

I am using "karser/karser-recaptcha3-bundle": "^0.1.7" on Symfony v4.4.4 as follows:

$builder->add(
	'captcha',
	Recaptcha3Type::class,
	[
		'constraints' => new Recaptcha3(),
		'action_name' => 'form_submission',
	]
);

In the karser_recaptcha3.yml I have the following config:

karser_recaptcha3:
    site_key: '%env(RECAPTCHA3_KEY)%'
    secret_key: '%env(RECAPTCHA3_SECRET)%'
    score_threshold: 0.1
    enabled: true

I have a form which then shows the 'Protected by reCAPTCHA' logo which suggests the keys are working in the front end. Now when I submit a form after changing the threshold, using a VPN to use some spam IPs as well as changing the device header into GoogleBot2.1, the form still submits without showing any captcha.

I then went to the Recaptcha3Validator class and did a dd of the response from this line of code and got nothing:

$response = $this->recaptcha->verify($value, $ip);

I even tried to do a few dd on many places in the bundle but I feel like I am missing a step here which means the validation is never happening when a form is submitted. Could you please suggest where I might be going wrong or is there additional steps that need to be implemented for the captcha to show on form submit?

Your computer or network may be sending automated queries - error always showing on localhost

Hi everyone,

After I followed the doc for the implementation of the bundle, I am facing an issue. I don't know if it is linked to the bundle or to Recaptcha itself but I have every time I submit my form in local :

"Your computer or network may be sending automated queries"

I am working with Symfony 5 and I have done the little configuration as possible as mentioned in the readme.

my karser_recaptcha3.yaml

karser_recaptcha3:
    site_key: "%env(RECAPTCHA3_KEY)%"
    secret_key: "%env(RECAPTCHA3_SECRET)%"
    score_threshold: 0.5
    enabled: true

my form

  namespace App\Form;
  
  use Symfony\Component\Form\AbstractType;
  use Karser\Recaptcha3Bundle\Form\Recaptcha3Type;
  use Symfony\Component\Form\FormBuilderInterface;
  use Symfony\Component\OptionsResolver\OptionsResolver;
  use Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3;
  use Symfony\Component\Form\Extension\Core\Type\SubmitType;
  
  class VoteType extends AbstractType
  {
      public function buildForm(FormBuilderInterface $builder, array $options)
      {
          $builder
              ->add('captcha', Recaptcha3Type::class, [
                  'constraints' => new Recaptcha3(),
                  'action_name' => 'homepage'
              ])
              ->add('submit', SubmitType::class, [])
              ;
          ;
      }
  
      public function configureOptions(OptionsResolver $resolver)
      {
          $resolver->setDefaults([]);
      }
  }

Thanks a lot for your answer,

Nayan

Update docs/config for symfony Recipe and symfony 5

I have installed this bundle on a fresh SF5 application.
but the generated config files does not match with your docs.

  • config/packages/goggle_recaptcha.yaml instead of config/packages/karser_recaptcha3.yaml
  • in .env "GOOGLE_RECAPTCHA_SITE_KEY" and "GOOGLE_RECAPTCHA_SECRET" instead of RECAPTCHA3_KEY=my_site_key
    RECAPTCHA3_SECRET=my_secret

is this config obsolet?
karser_recaptcha3:
site_key: '%env(RECAPTCHA3_KEY)%'
secret_key: '%env(RECAPTCHA3_SECRET)%'
score_threshold: 0.5
when yes, why the config-tree has this dependencies?

Unable to run in a API orientation

Hi everyone!

my application environnement is:
-> angular 16 (i use postMan to test this login endPoint)
-> SF 6
---> LexikJWTAuthenticationBundle

###> karser/karser-recaptcha3-bundle ### RECAPTCHA3_KEY=xxxxxxxx RECAPTCHA3_SECRET=xxxx RECAPTCHA3_ENABLED=1 ###< karser/karser-recaptcha3-bundle ###

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

karser_recaptcha3: site_key: '%env(RECAPTCHA3_KEY)%' secret_key: '%env(RECAPTCHA3_SECRET)%' score_threshold: 0.7 enabled: true

{ "type": "project", "license": "proprietary", "minimum-stability": "stable", "prefer-stable": true, "require": { "php": ">=8.1", "ext-ctype": "*", "ext-iconv": "*", "doctrine/doctrine-bundle": "^2.10", "doctrine/doctrine-migrations-bundle": "^3.0", "doctrine/orm": "^2.16", "egulias/email-validator": "^4.0", "friendsofsymfony/rest-bundle": "^3.5", "gesdinet/jwt-refresh-token-bundle": "^1.1", "jms/serializer-bundle": "^5.3", "karser/karser-recaptcha3-bundle": "^0.1.24", "lexik/jwt-authentication-bundle": "^2.19", "nelmio/api-doc-bundle": "^4.12", "nelmio/cors-bundle": "^2.3", "symfony/asset": "6.3.*", "symfony/console": "6.3.*", "symfony/dotenv": "6.3.*", "symfony/flex": "^2", "symfony/framework-bundle": "6.3.*", "symfony/runtime": "6.3.*", "symfony/twig-bundle": "6.3.*", "symfony/yaml": "6.3.*" }

I have been following the different steps until the API orientation part.

Am i suppose to be able to run this bundle at this part of the configuration procedure?
I haven't got any error even if I do not send the reCaptcha token.

--> (@post)http://localhost:8000/api/login_check
-->
{
"password":"test",
"email":"[email protected]",
"captcha" : ""

}

thank you all for the returns :-)

You have requested a non-existent parameter "twig.form.resources"

Hello,

After bundle installation I've got following error:

[Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException]
You have requested a non-existent parameter "twig.form.resources".
...
Symfony\Component\DependencyInjection\Container->getParameter() at vendor/karser/karser-recaptcha3-bundle/DependencyInjection/KarserRecaptcha3Extension.php:24

I would suggest a minor change to the injectTemplate() method in KarserRecaptcha3Extension, but not really sure it's the right way to fix the error:

$resources = $container->hasParameter('twig.form.resources')
    ? $container->getParameter('twig.form.resources')
    : [];

I'm using Symfony 4.4.5, PHP 7.2.28 if that matters

The captcha value is missing. API method

Hello, I work in API mode on symfony 5 (ApiPlatform) with nuxtjs in Front. After implementing your bundle. I get as error: The captcha value is missing. Thank you for your reply.

SF 5.1 Configurator\ref deprecation in config/services.php

I noticed that SF made a Symfony\Component\DependencyInjection\Loader\Configurator\ref deprecated.
You should change

use function Symfony\Component\DependencyInjection\Loader\Configurator\ref;
to
use function \Symfony\Component\DependencyInjection\Loader\Configurator\service;

and then in your args ref -> service

google.com not accessible from China

We use your bundle on our shop through a plugin prometee/sylius-google-recaptcha-v3-plugin without any issue.

Except when Chinese people try to fill a form (with a GRecaptchaV3 embeded) from China, apparently this is a known issue and google assistance page is telling us to replace google.com by recaptcha.net. You can find more info about this reading the StackOverflow answer here :
https://stackoverflow.com/questions/57827914/google-recaptcha-in-china

One way to fix this is to simply extends the template, but may I suggest to be able to switch this from a config switch ?

# config/packages/karser_recaptcha3.yaml (or app/config/config.yml if using Symfony3)

karser_recaptcha3:
    use_recaptcha_net: true

(A comment can be also linked to this config field with the link to the StackOverflow page)

And then add a third constructor argument to the Recaptcha3Type to allow the twig template to switch domain accordingly.

Any suggestion or advise before I start to propose a PR ?

Symfony 5 compatibility

Hey! Is there any chance to make this version compatible with Symfony 5.x? I think you just need to update composer and everything it will be alright.

Support for Content-Security Policy

Hello,

For supporting website with Content-Security Policy, we must include a nonce for inline JavaScript. I would like to suggest a new parameter :

$builder->add('captcha', Recaptcha3Type::class, [
    'constraints' => new Recaptcha3(),
    'action_name' => 'homepage',
    'nonceCSP' => $nonceCSP
]);

so it can be used in :


<script nonce="{{ nonceCSP }}">
    var recaptchaCallback_form_captcha = function() {
    grecaptcha.execute('<YOUR-RECAPTCHA-KEY>', {action: 'landing'}).then(function(token) {
    document.getElementById('form_captcha').value = token;
    });
    };
    </script>

Thank you!

Translation messages

How can I set the captcha language for different locales?
Is there some option for this?

symfony/templating is deprecated

https://symfony.com/doc/4.4/templating/PHP.html

symfony/templating has been deprecated from 4.3 and will be removed in 5. The solution is to stop depending on symfony/templating and just to use Twig. Otherwise using karser/karser-recaptcha3-bundle will pull in symfony/templating and throw lots of deprecation warnings.

Edit: I'm not sure how necessary this is. It does seem in the 4.4 upgrade instructions we can disable the TwigEngine loader and get rid of the deprecations.

The captcha value is missing

Hello,

I'm continually getting "The captcha value is missing" message.

This is my first PHP project for more than a decade :)

The browser says that the form is successfully posted:

Form data:

contact_us[captcha]: 
03AGdBq26czW2_CFHbLvnvfy-qrzIYWMr1drr1WhcEyjJrElxSTHpG1MepvjeZF8Yafd2guBXZ9bbAMbSjdOJnli0RleE2f7rtht9-iRtKwxFqzn4tGn7ReDYesItAv8OvgbR7lF3Zw6o8IJG0QZlSL_aZrywQVfXUZ9TCsBYG0gDeW-X-ymG97XqgXbHX43bTe6oOmel5wNk94W2FTtiXgVxR0TLdG5QRnMVXPL06Cu6Y-TMEd5KH0hrADiSnZG7EZaTQSJNiVcDEB9WSX-rcnacgiHzkIgLVs9f6NrDpmS2lBpl1Lv6OCaYg0Jz1EFJx_fr2s_fP2vltuOWHOHojyWjdC30rJySUZ_35Yvslh4A8TmiNfGDn7bRlO2c990GVB9f5VINTa9yn1Zb6dAcZxDlFXrWg83Q5gV9wSL5y6ACALvrdi1IwvyqhDiK2TDydwxm741VMvttN
contact_us[_token]:
9af332ff29b1fead7c8a058.VhAT8CLqFjeAw7lsC2tQ_gKLAhNUODTRuizgDsU_HuA.LCMipHK4Z3i5p_obbj0XjDfUXVwGdXi76xuCfqZUf9MsPWCBRb9mR62FjQ

But debug details look strange for me:
debug

I can share the entire project :)

action_name in form

Do you have an example of the form integration where i can specify a custom action_name? Thanks.

Unable to create and run test

I followed your readme and successfully integrate google recaptcha3 to my site. It works fine. But when testing it throws error.

Errror:

App\Tests\Form\ContactTypeTest::testSubmitValidData                          
ArgumentCountError: Too few arguments to function Karser\Recaptcha3Bundle\Form\Recaptcha3Type::__construct(), 0 passed in /home/sudhakar/SudhakarK/NB/2022/FZMFW/vendor/symfony/form/FormRegistry.php on line 81 and exactly 3 expected         
                                                                                
/home/sudhakar/SudhakarK/NB/2022/FZMFW/vendor/karser/karser-recaptcha3-bundle/Form/Recaptcha3Type.php:22                                                        
/home/sudhakar/SudhakarK/NB/2022/FZMFW/vendor/symfony/form/FormRegistry.php:81  
/home/sudhakar/SudhakarK/NB/2022/FZMFW/vendor/symfony/form/FormFactory.php:67   
/home/sudhakar/SudhakarK/NB/2022/FZMFW/vendor/symfony/form/FormBuilder.php:91   
/home/sudhakar/SudhakarK/NB/2022/FZMFW/vendor/symfony/form/FormBuilder.php:238  
/home/sudhakar/SudhakarK/NB/2022/FZMFW/vendor/symfony/form/FormBuilder.php:189  
/home/sudhakar/SudhakarK/NB/2022/FZMFW/vendor/symfony/form/FormFactory.php:31   
/home/sudhakar/SudhakarK/NB/2022/FZMFW/tests/Form/ContactTypeTest.php:33 

My works:
I'm not using .env for config. I build symfony from microkernel as per Building your own Framework with the MicroKernelTrait

CODE:
ContactType:

<?php

namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use App\Entity\Contact;
use Karser\Recaptcha3Bundle\Form\Recaptcha3Type;
use Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3;

class ContactType extends AbstractType {

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options): void {
        $builder
                ->add('name', TextType::class, ['attr' => ['class' => 'form-control', 'placeholder' => 'name']])
                ->add('email', EmailType::class, ['attr' => ['class' => 'form-control', 'placeholder' => 'email']])
                ->add('phone', TextType::class, ['attr' => ['class' => 'form-control', 'placeholder' => 'contact']])
                ->add('message', TextareaType::class, ['attr' => ['class' => 'form-control', 'placeholder' => 'info', 'rows' => '5']])
# TEST PASSES WHEN I REMOVE 'captcha' (following lines completely)
                ->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 }}']),
                    'action_name' => 'contactpage',
                    'locale' => 'en',
        ]);
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver): void {
        $resolver->setDefaults(array(
            'data_class' => Contact::class,
            'csrf_protection' => true,
            'csrf_field_name' => '_token',
            'csrf_token_id' => 'task_item',
        ));
    }

}

Here # TEST PASSES WHEN I REMOVE 'captcha' (I mentioned in above code)

ContactTypeTest:

<?php

/*
 * Copyright (C) 2009 - 2022
 * Author:   Sudhakar Krishnan <[email protected]>
 * License:  http://www.featuriz.in/licenses/LICENSE-2.0
 * Created:  Mon, 14 Nov 2022 13:30:28 IST
 */

namespace App\Tests\Form;

use App\Form\ContactType;
use App\Entity\Contact;
use Symfony\Component\Form\Test\TypeTestCase;

/**
 * Description of ContactTypeTest
 *
 * @author Sudhakar Krishnan <[email protected]>
 */
class ContactTypeTest extends TypeTestCase {

    public function testSubmitValidData() {
        $formData = [
            'name' => 'My Name',
            'email' => 'info',
            'phone' => '123',
            'message' => 'hi',
        ];

        $model = new Contact();
        // $model will retrieve data from the form submission; pass it as the second argument
        $form = $this->factory->create(ContactType::class, $model);

        $expected = new Contact();
        // ...populate $expected properties with the data stored in $formData
        $expected->setName("My Name")->setEmail("info")->setPhone("123")->setMessage("hi");

        // submit the data to the form directly
        $form->submit($formData);

        // This check ensures there are no transformation failures
        $this->assertTrue($form->isSynchronized());

        // check that $model was modified as expected when the form was submitted
        $this->assertEquals($expected, $model);

        $this->assertEquals($expected, $form->getData());

        $view = $form->createView();
        $children = $view->children;

        foreach (array_keys($formData) as $key) {
            $this->assertArrayHasKey($key, $children);
        }
    }

    public function testCustomFormView() {
        $formData = new Contact();
        // ... prepare the data as you need
        $formData->setName("My Name")->setEmail("info")->setPhone("123")->setMessage("hi");

        // The initial data may be used to compute custom view variables
        $view = $this->factory->create(ContactType::class, $formData)
                ->createView();

        $this->assertArrayHasKey('id', $view->vars);
        $this->assertArrayHasKey('name', $view->vars);
        $this->assertArrayHasKey('method', $view->vars);
        $this->assertSame('contact', $view->vars['id']);
        $this->assertSame('contact', $view->vars['name']);
        $this->assertSame('POST', $view->vars['method']);
    }

}

I don't know what I'm doing wrong here.
My config:

karser_recaptcha3:
    site_key: "XXXSECRET"
    secret_key: "XXXSECRET"
    score_threshold: 0.5
    enabled: true

when@prod:
    karser_recaptcha3:
        site_key: "XXXSECRET"
        secret_key: "XXXSECRET"
        score_threshold: 0.5
        enabled: true        
        
when@test:
    karser_recaptcha3:
        enabled: false

Captcha always invalid when form is sent multiple times with ajax

Hello!

I'm having an issue while sending a form with a recaptcha input by ajax request.

My problem is:

  • I send a form with an error (any invalid field)
  • I re-render the form
  • When I fix my invalid field and send the form again, it tells me the "Your computer or network may send invalid request"

My route used as form action is the Sylius ResourceController:createAction and it renders a template with only the form

My javascript:

import axios from 'axios'

export default () => {
    const container = document.querySelector('#contact-form')

    if (!container) return

    initForm(container)
}


const initForm = (container) => {
    const form = container.querySelector('form')

    if (!form) return

    form.addEventListener('submit', e => {
        e.stopPropagation()
        e.preventDefault()

        axios.post(form.action,
            new FormData(form),
            {
                headers: { 'Content-Type': 'multipart/form-data' }
            }
            ).then(({data}) => {
            container.innerHTML = data;
            initForm(container)
        })
    })
}

My form:

class ContactRequestType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array                $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            // ...
            ->add('captcha', Recaptcha3Type::class, [
                'mapped'      => true,
                'constraints' => [
                    new Recaptcha3(),
                ],
            ]);
    }

    // ...
}

Template injection not working on Symfony 4.2

Hi,

thanks for that bundle. I had an issue with Symfony 4.2 when injecting the template.

$resources[] = 'KarserRecaptcha3Bundle:Form:karser_recaptcha3_widget.html.twig';

Would give an error 500 with Symfony 4.2. I had to change this to:

$resources[] = '@KarserRecaptcha3/Form/karser_recaptcha3_widget.html.twig';

class "Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3Validator" does not exist

Hi,

Thanks for your work.
I've been able to make it work one time but since it throw an error while trying to reach the form page :

Cannot autowire argument $recaptcha of "App\Controller\ContactController::index()": it references class "Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3Validator" but no such service exists. You should maybe alias this class to the existing "karser_recaptcha3.validator" service.

Controller looks like that :

use Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3Validator;

class ContactController extends AbstractController
{
/**
* @route("/contact", name="contact")
*/
public function index(Request $request, MailerInterface $mailer, Recaptcha3Validator $recaptcha): Response
{

    $form = $this->createForm(ContactType::class);
    $form->handleRequest($request);

    if ($form->isSubmitted() && $form->isValid()) {

        $score = $recaptcha->getLastResponse()->getScore();

...

I've tried to remove / reinstall the package without success...

Symfony 5.2.3
Php : 7.4.15

Any thoughts?

Thanks :)

Triggering captcha on form submit

Hi,
Not sure how to implement the following behavior: I don't want the captcha dialog to open up in page load, but when the user submits the form. The twig widget loads the recaptcha js and automatically calls the recaptchaCallback_form_captcha, thus opening up the captcha dialog.

<script src="https://www.google.com/recaptcha/api.js?render=<YOUR-RECAPTCHA-KEY>&onload=recaptchaCallback_form_captcha" async defer></script>

I don't know how to interpret your example , under or on form post. The captcha is already triggered on page load.

Thanks!

Recaptcha suddenly stoped working

Hey,

I'm not sure what exactly happened here, but suddenly following message started appearing in Chrome console and recaptcha v3 stopped working.

The resource https://www.recaptcha.net/recaptcha/api.js?render=6Ldd4v8cAAAAAHTv6F5WUKKunVITU-VKkJ5_6WkL&hl=en&onload=recaptchaCallback_student_login_captcha was preloaded using link preload but not used within a few seconds from the window's load event. Please make sure it has an appropriate as value and it is preloaded intentionally.

No changes in application were made.

Upon further investigation I noticed that script from api.js is not executed. But when pasted contents of api.js directly to vendor/karser/karser-recaptcha3-bundle/Resources/views/Form/karser_recaptcha3_widget.html.twig it was working again.

When poking further I found that recaptcha starts working again if "defer" directive is removed from script tag.
<script type="text/javascript" src="https://{{ form.vars.host }}/recaptcha/api.js?render={{ form.vars.site_key }}&hl={{ form.vars.locale }}&onload=recaptchaCallback_{{ validJsId }}" async{% if form.vars.script_nonce_csp is defined %} nonce="{{ form.vars.script_nonce_csp }}"{% endif %}></script>... but only when karser_recaptcha3.host is set to 'www.recaptcha.net'.

Violation "Could not connect to service"

Hi,

I'm having an issue with the validator, it keep raising a violation "Could not connect to service"
I've followed the troubleshooting checklist. I've had and resolved issues with the site key & domains. Setting the SCP didn't change anything.
If a put the score threshold too high, the validator return a violation 'score too low', making me think that I am in fact getting a response from google.

How can I at least get more information from this error ?

Thanks.

Required dependencies

Could we make symfony/form as an optional dep? For example I don't use forms in app but it's installed because only this package requires them.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.