top of page
Search

Implementing v3 reCAPTCHA Validation for REST API Endpoint in Magento 2

Introduction


In today's digital landscape, online security is paramount, and one effective way to protect your Magento 2 store from spam and abuse is by integrating reCAPTCHA. Magento 2 supports Google's reCAPTCHA, including the latest version - v3. In this blog post, we'll guide you through implementing v3 reCAPTCHA validation for a REST API endpoint in Magento 2.


Step 1: Obtain reCAPTCHA v3 API Keys


Obtain reCAPTCHA v3 API Keys for Magento 2


  Sign Up for reCAPTCHA:


  • Go to the reCAPTCHA website.

  • Click "Admin Console" and sign in or create an account.


Register a New Site:


  • Click the "+" icon.

  • Choose "reCAPTCHA v3" and "I'm not a robot" Checkbox.

  • Enter your domains and accept the terms.

  • Click "Submit."


Get API Keys:

  • After submission, find your Site Key and Secret Key.

  • Site Key is for the client and Secret Key is for the server.


Google recaptcha

Step 2: Create a REST API endpoint


First of all, let’s create a simple REST API endpoint for the checkout page. Create new module names as Payment and add PaymentInterface to the Api folder:


<?php
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment for Magento 2
 */

declare(strict_types=1);

namespace Barwenock\Payment\Api;

interface PaymentInterface
{
    /**
     * Send payment data api
     *
     * @return mixed
     */
    public function sendPaymentData();
}

Then, add realization for this function under the Model folder:

<?php
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment for Magento 2
 */

declare(strict_types=1);

namespace Barwenock\Payment\Model;

class Payment implements \Barwenock\Payment\Api\PaymentInterface
{
    /**
     * Implementation of sending payment data
     *
     * @return void
     */
    public function sendPaymentData()
    {
        //Some logic for handling payment information
    }
}

And create di.xml for dependency injection between Api and Model. Also, configured the service class  using the webapi.xml

 

di.xml:

<?xml version="1.0"?>
<!--
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment for Magento 2
 */
 -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <preference for="Barwenock\Payment\Api\PaymentInterface" type="Barwenock\Payment\Model\Payment" />
</config>

webapi.xml:

<?xml version="1.0"?>
<!--
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment for Magento 2
 */
 -->
<routes xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Webapi:etc/webapi.xsd">
    <route url="/V1/barwenock/payment-send" method="POST">
        <service class="Barwenock\Payment\Api\PaymentInterface" method="sendPaymentData"/>
        <resources>
            <resource ref="anonymous"/>
        </resources>
    </route>
</routes>

Step 3: reCAPTCHA v3 REST validation:


Magento 2 has already an implementation of validation for rest. It is under:

module-re-captcha-webapi-rest/Plugin/RestValidationPlugin.php


recapcha magento

So, now we need only pass the reCAPTCHA token into the header of our request. But how to generate it?


Step 4: Configure ReCaptcha and generate a token


Let’s create an additional module named PaymentRecaptcha and add system.xml


<?xml version="1.0"?>
<!--
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment Captcha for Magento 2
 */
 -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
    <system>
        <section id="recaptcha_frontend">
            <group id="type_for">
                <field id="barwenock_payment" translate="label" type="select" sortOrder="200" showInDefault="1"
                       showInWebsite="1" showInStore="0" canRestore="1">
                    <label>Enable for Barwenock Payment form</label>
                    <source_model>Magento\ReCaptchaAdminUi\Model\OptionSource\Type</source_model>
                </field>
            </group>
        </section>
    </system>
</config>

After module installation and cache cleaning go to Stores→Configuration→Security→Google reCAPTCHA Storefront.


Open the reCAPTCHA v3 Invisible tab and paste the Google API Website Key & Google API Secret Key.


recaptcha v3

Then, open the Storefront tab and select Enable for Add To Cart – reCAPTCHA v3 Invisible.             

 

Now, let’s add our reCAPTCHA provider to the checkout provider. Create frontend/di.xml

<?xml version="1.0"?>
<!--
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment Captcha for Magento 2
 */
 -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Model\CompositeConfigProvider">
        <arguments>
            <argument name="configProviders" xsi:type="array">
                <item name="recaptcha_provider" xsi:type="object">Barwenock\PaymentRecaptcha\Model\CheckoutConfigProvider</item>
            </argument>
        </arguments>
    </type>
</config>

After that create our  Model/CheckoutConfigProvider to provide our payment captcha status:


<?php
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment Captcha for Magento 2
 */

declare(strict_types=1);

namespace Barwenock\PaymentRecaptcha\Model;

class CheckoutConfigProvider implements \Magento\Checkout\Model\ConfigProviderInterface
{
    /**
     * @var \Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface
     */
    private $isCaptchaEnabled;

    /**
     * @param \Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface $isCaptchaEnabled
     */
    public function __construct(
        \Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface $isCaptchaEnabled
    ) {
        $this->isCaptchaEnabled = $isCaptchaEnabled;
    }

    /**
     * @inheritdoc
     */
    public function getConfig()
    {
        return [
            'barwenock_payment' => $this->isCaptchaEnabled->isCaptchaEnabledFor('barwenock_payment')
        ];
    }
}

Also, provide our provider to add configuration for endpoints.

Create di.xml:


<?xml version="1.0"?>
<!--
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment Captcha for Magento 2
 */
 -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\ReCaptchaWebapiApi\Model\CompositeWebapiValidationConfigProvider">
        <arguments>
            <argument name="providers" xsi:type="array">
                <item name="barwenock_payment" xsi:type="object">Barwenock\PaymentRecaptcha\Model\WebapiConfigProvider</item>
            </argument>
        </arguments>
    </type>
</config>

And Model/WebapiConfigProvider.php:


<?php
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment Captcha for Magento 2
 */

declare(strict_types=1);

namespace Barwenock\PaymentRecaptcha\Model;

/**
 * @inheritdoc
 */
class WebapiConfigProvider implements \Magento\ReCaptchaWebapiApi\Api\WebapiValidationConfigProviderInterface
{
    /**
     * Payment captcha ID
     */
    private const PAYMENT_CAPTCHA_ID = 'barwenock_payment';

    /**
     * @var \Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface
     */
    private $isEnabled;

    /**
     * @var \Magento\ReCaptchaUi\Model\ValidationConfigResolverInterface
     */
    private $configResolver;

    /**
     * @param \Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface $isEnabled
     * @param \Magento\ReCaptchaUi\Model\ValidationConfigResolverInterface $configResolver
     */
    public function __construct(
        \Magento\ReCaptchaUi\Model\IsCaptchaEnabledInterface $isEnabled,
        \Magento\ReCaptchaUi\Model\ValidationConfigResolverInterface $configResolver
    ) {
        $this->isEnabled = $isEnabled;
        $this->configResolver = $configResolver;
    }

    /**
     * @inheritDoc
     */
    public function getConfigFor(\Magento\ReCaptchaWebapiApi\Api\Data\EndpointInterface $endpoint):
        ?\Magento\ReCaptchaValidationApi\Api\Data\ValidationConfigInterface
    {
        if ($endpoint->getServiceClass() === \Barwenock\Payment\Api\PaymentInterface::class
            && $this->isEnabled->isCaptchaEnabledFor(self::PAYMENT_CAPTCHA_ID)) {
            return $this->configResolver->get(self::PAYMENT_CAPTCHA_ID);
        }

        return null;
    }
}


Finally, we need to realize the generation of the X-ReCaptcha token and pass it into the header of the REST API endpoint.

Create view/frontend/layout/checkout_index_index.xml:


<?xml version="1.0"?>
<!--
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment Captcha for Magento 2
 */
 -->
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
    <head>
        <script src="Barwenock_PaymentRecaptcha::js/reCaptchaPayment.js"/>
    </head>
</page>


Now create js/reCaptchaPayment.js with the realization of the generation token:


1) Replace YOUR_GOOGLE_RECAPTCHA_SITE_KEY with your Google reCAPTCHA public site key.

2) Replace the Ajax URL with your endpoint URL


<!--
/**
 * @author Barwenock
 * @copyright Copyright (c) Barwenock
 * @package Payment Captcha for Magento 2
 */
 -->
/* global grecaptcha */
require(
    [
        'jquery'
    ],
    function ($) {
        'use strict';

        // Dynamically add the reCAPTCHA script to the document
        let recaptchaScript = document.createElement('script');
        let googleApiKey = 'YOUR_GOOGLE_RECAPTCHA_SITE_KEY';
        recaptchaScript.src = 'https://www.google.com/recaptcha/api.js?render=' + googleApiKey;
        document.head.appendChild(recaptchaScript);

        // Wait for the reCAPTCHA script to be loaded
        recaptchaScript.onload = function () {
            grecaptcha.ready(function () {
                grecaptcha.execute(googleApiKey, {action: 'submit'}).then(function (token) {
                    $.ajax({
                        url: 'https://magento2.ddev.site/index.php/rest/V1/barwenock/payment-send',
                        type: 'POST',
                        headers: {
                            'x-recaptcha': token // the token is passed in the header
                        },
                        success: function (response) {
                            console.log('Success')
                        },
                        error: function (xhr, status, error) {
                            console.log('Error')
                        }
                    });
                });
            });
        }
    }
);

In conclusion


Implementing reCAPTCHA v3 validation for the REST API endpoint in Magento 2 is an important step in improving security and preventing automated attacks on your website. Using reCAPTCHA v3 allows you to analyze user behavior without having to actively interact with the page, thereby improving user experience while protecting against bots.


143 views0 comments
bottom of page