Skip to content

Implementation

Fabian Wennink edited this page Oct 31, 2023 · 2 revisions

The following instructions will guide you through the process of implementing IconCaptcha in your own application. Before proceeding, ensure that you've read the Getting Started guide and you are positive all requirements have been met.

Step 1: PHP

We start of with implementing the server-side code to process and validate the captcha requests.

Request Processing

The example code show below is responsible for serving captcha challenges and processing all widget requests. This script must be accessible as an endpoint (e.g. in a framework controller) in your application, to be called by the widget in the client-side. In your JavaScript code (later in step 3), this endpoint must be specified in the general.endpoint configuration option.

The example code can also be found in the /examples folder as captcha-request.php.

Configuration

The captcha-config.php file, which is shown being included in the all server-side examples, contains the IconCaptcha configuration. You must require this configuration file and provide it to the IconCaptcha class during initialization. You can find a template for this configuration file here: captcha-config.php.

The configuration options are very extensive and allow you to tweak many aspects of IconCaptcha. Additionally, you have the ability to hook into various stages of the challenge handling processes and execute custom code if needed. For detailed information, please refer to the Hooks wiki page.

Example

Note

Starting a session with session_start(); is only required if you have configured any of the configuration options to use a session driver. Check your configuration to see whether you need to start a session.

<?php

// THIS CODE CAN BE FOUND IN THE /examples FOLDER AS 'captcha-request.php'.

// Load the autoloader.
require_once __DIR__ . '/path/to/vendor/autoload.php';

use IconCaptcha\IconCaptcha;

try {

    // Start a session.
    // * Only required when using any 'session' driver in the configuration.
    session_start();

    // Load the IconCaptcha configuration.
    // THE DEFAULT CONFIGURATION FILE CAN BE FOUND IN THE /examples FOLDER.
    $config = require 'captcha-config.php';

    // Create an instance of IconCaptcha.
    $captcha = new IconCaptcha($config);

    // Handle the CORS preflight request.
    // * If you have disabled CORS in the configuration, you may remove this line.
    $captcha->handleCors();

    // Process the request.
    $captcha->request()->process();

    // Request was not supported/recognized.
    http_response_code(400);

} catch (Throwable $exception) {

    http_response_code(500);

    // Add your custom error logging handling here.

}

1.2. Processing the form

In addition to the challenge processing code, you'll need to handle the submitted form to validate that a captcha was successfully completed. Chances are you already have code in place to process your form, so the remaining task is to incorporate captcha validation.

The example below illustrates this process. Similar to the previous code snippet, you'll need to load the autoloader, configuration, and initialize an IconCaptcha instance.

Validate Form

You can validate the $_POST variable using $captcha->validate($_POST);. This function returns an object that includes the success() function. Calling this function will return a boolean, indicating whether the captcha was completed successfully or not. If the captcha was completed successfully (returns true), you can proceed with your form submission. However, if it returns false, the captcha was not completed, and you should handle this situation accordingly.

To determine the reason for why the captcha was not completed, you can check the error code by using getErrorCode() on the same variable. For more information about the various error codes you might encounter, please refer to the Validation wiki page.

Example

Note

Starting a session with session_start(); is only required if you have configured any of the configuration options to use a session driver. Check your configuration to see whether you need to start a session.

<?php

// Load the autoloader.
require_once __DIR__ . '/path/to/vendor/autoload.php';

use IconCaptcha\IconCaptcha;

// Start a session.
// * Required when using any 'session' driver in the configuration.
// * Required when using the IconCaptcha Token, referring to the use of 'IconCaptchaToken' in your form (see HTML step).
session_start();

// If the form has been submitted, validate the captcha.
if(!empty($_POST)) {

    // Load the IconCaptcha configuration.
    // THE DEFAULT CONFIGURATION FILE CAN BE FOUND IN THE /examples FOLDER.
    $config = require 'captcha-config.php';

    // Create an instance of IconCaptcha.
    $captcha = new IconCaptcha($config);

    // Validate the captcha.
    $validation = $captcha->validate($_POST);

    // Confirm the captcha was validated.
    if($validation->success()) {
        // The captcha is valid. Execute your form processing code here.
    } else {
        // The captcha is invalid. To see the reason, use $validation->getErrorCode()
        // Refer to the wiki for more information about what each error code means.
    }
}

Step 2: HTML

Add the IconCaptcha widget element inside the form you wish to protect. The widget and challenges will be generated inside this element. Use the data-theme attribute to specify which theme should be used by the widget. By default, IconCaptcha comes with 2 themes: light and dark. If no theme is set, the light theme will be used.

To further protect your form, a CSRF token (generated with PHP) may be added as shown in the example below. If you are unable to run PHP in your HTML page, this feature will not function and should be disabled in the PHP configuration as described here. For more information about this token, please read the Token wiki page.

<form method="post">

    <input type="text" name="name" />

    <!-- The widget will be rendered in this element. -->
    <div class="iconcaptcha-widget" data-theme="light"></div>
    
    <!-- Additional security feature to prevent CSRF. -->
    <!-- Optional, but highly recommended. Configure in config ('token' option). -->
    <?php echo \IconCaptcha\Token\IconCaptchaToken::render(); ?>

    <button type="submit">Submit</button>

</form>

<!-- Include the assets. Change the paths accordingly or use the CDN assets. -->
<link href="/path/to/assets/css/iconcaptcha.min.css" rel="stylesheet" type="text/css">
<script src="/path/to/assets/js/iconcaptcha.min.js" type="text/javascript"></script>

CDN

Instead of loading the iconcaptcha.min.css stylesheet and iconcaptcha.min.js script from your own server, you may also opt for using a CDN.

<link href="https://cdn.jsdelivr.net/gh/fabianwennink/[email protected]/dist/css/iconcaptcha.min.css" rel="stylesheet" type="text/css">
<script src="https://cdn.jsdelivr.net/gh/fabianwennink/[email protected]/dist/js/iconcaptcha.min.js" type="text/javascript"></script>

When using a CDN, you should be aware of the minor loss of control over the loaded content. This is because content is retrieved from a remote server rather than your own. It's advisable to only trust reputable CDN providers. Used as an example, jsDelivr is a highly reliable CDN with strong backing from reputable companies, and is capable of serving scripts directly from GitHub repositories.

Step 3: JavaScript

After having prepared your form, it's time to render the widget. To do so, you should add the code shown below to your webpage. Make sure to place it below the <script> and <style> tags shown in the HTML code example above, as the icon-captcha.min.js script must be loaded first.

You can listen to different events which are fired during the widget and challenge lifecycle. Read the Events wiki page for more information.

Both plain JavaScript and jQuery are supported and function exactly the same. Use the implementation you prefer. An example for jQuery can be found further down.

Important

The general.endpoint option must be set to a URL which points to the captcha-request.php shown in Step 1: PHP.

<script type="text/javascript">
    document.addEventListener('DOMContentLoaded', function() {
        IconCaptcha.init('.iconcaptcha-widget', {
            general: {
                endpoint: '/captcha-request.php', // required, change the path accordingly.
                fontFamily: 'inherit',
                credits: 'show',
            },
            security: {
                interactionDelay: 1500,
                hoverProtection: true,
                displayInitialMessage: true,
                initializationDelay: 500,
                incorrectSelectionResetDelay: 3000,
                loadingAnimationDuration: 1000,
            },
            locale: {
                initialization: {
                    verify: 'Verify that you are human.',
                    loading: 'Loading challenge...',
                },
                header: 'Select the image displayed the <u>least</u> amount of times',
                correct: 'Verification complete.',
                incorrect: {
                    title: 'Uh oh.',
                    subtitle: "You've selected the wrong image.",
                },
                timeout: {
                    title: 'Please wait.',
                    subtitle: 'You made too many incorrect selections.'
                }
            }
        });
    });
</script>

jQuery

If you wish to use jQuery, make sure that the jQuery library is loaded before initializing IconCaptcha.

<script src="//ajax.googleapis.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script>
<script type="text/javascript">
    $(document).ready(function() {
        $('.iconcaptcha-widget').iconCaptcha({
            // The captcha options go here like demonstrated in the example above.
        })
    });
</script>

Step 4: Test the widget

Now that you've implemented IconCaptcha, it's time to put it to the test. On the webpage where you've integrated the widget element and scripts, a widget should be visible and functional. Depending on your configuration, it will either display the 'Verify that you are human' message or load a challenge instantly.

Troubleshooting common errors

We're all human (no pun intended), and mistakes happen. Don't worry; here are some common issues and their solutions:

Widget is not displaying

If the widget isn't showing up, make sure the IconCaptcha script and stylesheet are being loaded by the browser. If these are being included without any issues, make sure you've used the correct element selector in both the HTML and JavaScript code. By default, this selector is iconcaptcha-widget. In your HTML, include the DIV element with the correct class in your form, like this: <div class="iconcaptcha-widget" data-theme="light"></div>. In your JavaScript code, ensure you've used the correct selector to initialize the script, like this: IconCaptcha.init('.iconcaptcha-widget', { ... });.

Widget is not loading a challenge

If the widget fails to load a challenge, it could indicate one of two issues. Either the JavaScript option general.endpoint is incorrectly configured and not reaching the correct endpoint on your server, or there's an issue with your server implementation.

First, ensure that the endpoint is configured correctly. If you're certain the endpoint is correct, double-check your server-side implementation. You can use the try/catch example provided in Step 1: PHP to catch errors in the exception handler and troubleshoot further.