Skip to content

How To Use

Fabian Wennink edited this page Nov 4, 2023 · 6 revisions

Requirements

  • PHP >= 5.6 with the GD extension installed and enabled.

If using the jQuery implementation (optional):

  • jQuery >= 1.12.4

Note: It's recommended to use the latest available version of jQuery instead of the minimum version of 1.12.4. The jQuery library is only required when using the jQuery implementation - see 'Usage' section below.

Download

  1. Download IconCaptcha for PHP.
  2. Download the IconCaptcha Front-End package.
  3. Unpack both repositories to somewhere on your computer.
  4. Drag the content of the dist/ folder of the IconCaptcha Front-End package into the assets/ folder of the IconCaptcha PHP package.
  5. Check the assets/ folder and make sure you see the following sub-folders: css/, icons/ and js/.

Note: To make it easier to test the example captchas, the Front-End package is already included in this repository. However, these files might not always be up-to-date. To ensure you always have the latest version, please follow the instructions above.

Usage

HTML

Add the IconCaptcha holder inside the form you want to protect. The captcha will be generated inside this holder element. Use the data-theme attribute to specify which theme should be used for the captcha. By default, IconCaptcha comes with 4 themes: light, legacy-light, dark and legacy-dark. If no (or an invalid) theme is given, IconCaptcha will default back to the light theme.

To further improve the security of your form, a custom CSRF token (_iconcaptcha-token) should be added as shown in the example. Note that if you can't run PHP in your HTML page, this feature will not function and should be disabled in the IconCaptcha PHP options (by settting the token option to false).

<form method="post">

    <!-- Additional security token to prevent CSRF. Optional but highly recommended - disable via IconCaptcha options. -->
    <input type="hidden" name="_iconcaptcha-token" value="<?= IconCaptcha::token() ?>"/>

    <!-- The IconCaptcha will be rendered in this element -->
    <div class="iconcaptcha-holder" data-theme="light"></div>
    
</form>

<!-- Include IconCaptcha script & stylesheet | Change paths according to your installation -->
<link href="../assets/css/icon-captcha.min.css" rel="stylesheet" type="text/css">
<script src="../assets/js/icon-captcha.min.js" type="text/javascript"></script>

JavaScript / jQuery

To initialize IconCaptcha on the client-side, the following code should be added to the page. Both plain JavaScript and jQuery are supported and function exactly the same. Use the implementation you prefer. Note that if you want to use the jQuery implementation, make sure that the jQuery library is loaded before initializing IconCaptcha.

<!-- Initialize IconCaptcha -->
<script type="text/javascript">
    
    // Plain JavaScript implementation.
    document.addEventListener('DOMContentLoaded', function() {
        IconCaptcha.init('.iconcaptcha-holder', {
            general: {
                validationPath: '../src/captcha-request.php', // required, change path according to your installation.
                fontFamily: 'Poppins',
                credits: 'show',
            },
            security: {
                clickDelay: 500,
                hoverDetection: true,
                enableInitialMessage: true,
                initializeDelay: 500,
                selectionResetDelay: 3000,
                loadingAnimationDelay: 1000,
                invalidateTime: 1000 * 60 * 2, // 2 minutes, in milliseconds
            },
            messages: {
                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 60 sec.',
                    subtitle: 'You made too many incorrect selections.'
                }
            }
        });
    });

    // OR use jQuery
    
    // IconCaptcha hooks into jQuery, if you rather use jQuery instead of plain JavaScript.
    // Note that the jQuery library should be loaded prior to initializing IconCaptcha.
    $(document).ready(function() {
        $('.iconcaptcha-holder').iconCaptcha({
            // The captcha options go here.
        })
    });
</script>

When using the jQuery implementation, add the following script to your page to load the jQuery library. Visit the jQuery website to get the latest version information.

<script src="//ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>

PHP

<?php
    // Start a session.
    session_start();

    // Include the IconCaptcha classes.
    require('../src/captcha-session.class.php');
    require('../src/captcha.class.php');

    use IconCaptcha\IconCaptcha;

    // Set the IconCaptcha options.
    IconCaptcha::options([
        'iconPath' => __DIR__ . '/../assets/icons/', // required, change path according to your installation.
        //'themes' => [
        //    'black' => [
        //        'icons' => 'light', // Which icon type should be used: light or dark.
        //        'color' => [20, 20, 20], // Array contains the icon separator border color, as RGB.
        //    ]
        //],
        'messages' => [
            'wrong_icon' => 'You\'ve selected the wrong image.',
            'no_selection' => 'No image has been selected.',
            'empty_form' => 'You\'ve not submitted any form.',
            'invalid_id' => 'The captcha ID was invalid.',
            'form_token' => 'The form token was invalid.'
        ],
        'image' => [
            'availableIcons' => 250, // Number of unique icons available.
            'amount' => [
                'min' => 5, // The lowest possible is 5 icons per challenge.
                'max' => 8 // The highest possible is 8 icons per challenge.
            ],
            'rotate' => true,
            'flip' => [
                'horizontally' => true,
                'vertically' => true,
            ],
            'border' => true
        ],
        'attempts' => [
            'amount' => 5,
            'timeout' => 60 // seconds.
        ],
        'token' => true
    ]);
    
    // If the form has been submitted, validate the captcha.
    if(!empty($_POST)) {
        if(IconCaptcha::validateSubmission($_POST)) {
            // Captcha submission was valid.
        } else {
            // Captcha submission was not valid.
        }
    }
?>

Options

The following options allow you to customize IconCaptcha to your liking. All the options are optional, however you might still want to take a look at the captchaAjaxFile option and make sure the path is set correctly.

PHP

Note: Every dot (.) in the Option value means it's a level deeper (nested array).

Option Description Default
iconPath The absolute path to the /assets/icons folder. This path will vary depending on how you implement IconCaptcha. For the example implementations, the absolute path __DIR__ . '/../assets/icons/' is used. Make sure this path is correct, or else no image can be generated by the server. null
themes See the 'Custom Themes' section at the bottom of the page.
messages See the 'PHP' message options in the 'Messages' section below.
image.availableIcons Number of unique icons available. By default, IconCaptcha ships with 250 unique icons. 250
image.amount.min The minimum amount of icons which can be shown in the captcha. Value must be lower or equal to the max. amount, not lower than 5 or higher than 8. 5
image.amount.max The maximum amount of icons which can be shown in the captcha. Value must be higher or equal to the min. amount, not lower than 5 or higher than 8. 8
image.rotate If the icons in the captcha should (sometimes) randomly rotate 90, 180, or 270 degrees. true
image.flip.horizontally If the icons in the captcha should (sometimes) randomly flip horizontally. true
image.flip.vertically If the icons in the captcha should (sometimes) randomly flip vertically. true
image.border If the separator between the icons should be visible. true
attempts.amount The number of times a user can make a wrong selection before having to wait some time (attempts.timeout). Will be ignored if attempts.timeout is set to 0. 5
attempts.timeout The time (in seconds) the user must wait before being able to use the captcha again, after reaching the set amount of wrong selections (attempts.amount). Set to 0 to disable the timeout function completely. 30
token If the CSRF token security feature should be used or not. When enabled, a hidden input field <input type="hidden" name="_iconcaptcha-token" value="<?= IconCaptcha::token() ?>"/> should be included in the form in which the captcha holder element is located (see the 'HTML form' in the 'Usage' section above). Optional, but highly recommended to leave enabled. true

JavaScript / jQuery

Note: Every dot (.) in the Option value means it's a level deeper (nested object).

Option Description Default
general.validationPath The path to captcha-request.php. Make sure you use the correct path else IconCaptcha won't be able to request the images or validate the input. null
general.fontFamily Changes the font family used by the captcha. Leaving this blank will default the captcha to using the page font family. null
general.credits Show, hide or disable the credits element of the captcha. Hiding the credits will still add the credits to the HTML, but it will not be visible (only to crawlers). Disabling the credits will neither show or add the HTML. Use show, hide or disabled. Please leave it enabled so people can find and use the captcha themselves. 'show'
security.clickDelay The time (in milliseconds) during which the user can't select an image. Set to 0 to disable. 1500
security.hoverDetection Prevent clicking on any icon until the cursor hovers over the captcha icon selection area. true
security.enableInitialMessage Show the initial 'verify that you are human' screen and make the user initialize the captcha. Keeping this enabled increases security and prevents additional load on the server. Set to false to instantly load the captcha data and image from the server upon page load (not recommended!). true
security.initializeDelay The time (in milliseconds) between the user clicking on the captcha to initialize it, and the captcha fetching it's data from the server. Set to 0 to instantly disable the delay. This option is ignored when security.enableInitialMessage is set to false. 500
security.selectionResetDelay The time (in milliseconds) it takes to reset the captcha after a wrong icon selection. Set to 0 to disable. 3000
security.loadingAnimationDelay The time (in milliseconds) during which a loading animation will play until the user input actually gets validated. 1000
security.invalidateTime The time (in milliseconds) after which an initialized captcha will automatically invalidate and reset itself. Set to 0 to disable. 1000 * 60 * 2
messages See the 'Javascript / jQuery' message options in the 'Messages' section below.

Messages

The following strings will be used by IconCaptcha, and can be changed / translated to your liking.

PHP

See the PHP implementation example at the 'Usage' section to see how to set these messages.

Message Default value
wrong_icon You've selected the wrong image.
no_selection No image has been selected.
empty_form You've not submitted any form.
invalid_id The captcha ID was invalid.
form_token The form token was invalid.
<?php
    IconCaptcha::options([
        ...
        'messages' => [
            'wrong_icon' => 'You\'ve selected the wrong image.',
            'no_selection' => 'No image has been selected.',
            'empty_form' => 'You\'ve not submitted any form.',
            'invalid_id' => 'The captcha ID was invalid.'
        ],
        ...
    ]);
?>

Javascript / jQuery

See the JavaScript / jQuery implementation example at the 'Usage' section to see how to set these messages.

Message Default value
messages.header Select the image displayed the <u>least</u> amount of times
messages.correct Verification complete.
messages.incorrect.title Uh oh.
messages.incorrect.subtitle You've selected the wrong image.
messages.timeout.title Please wait 60 sec.
messages.timeout.subtitle You made too many incorrect selections.
messages.initialization.verify Verify that you are human.
messages.initialization.loading Loading challenge...
<script type="text/javascript">
    document.addEventListener('DOMContentLoaded', function() {
        IconCaptcha.init('.iconcaptcha-holder', {
            messages: {
                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 60 sec.',
                    subtitle: 'You made too many incorrect selections.'
                }
            }
        });
    });
</script>

Events

Events will be triggered at various point in the client-side code. You can use a custom script to hook into the events and execute your own code if necessary. Note that you should not rely on these events, as these are purely client-side and can be triggered manually by attackers. ALWAYS PERFORM THE SERVER-SIDE VALIDATION!

Event Description
init Fires when the IconCaptcha has been fully built and the image details have been requested from the server.
selected Fires when the user selects an icon, regardless of if the icon is correct or not.
refreshed Fires when the user selected an incorrect icon and IconCaptcha is done refreshing it's challenge.
timeout Fires when the user made too many incorrect selections and the captcha is in timeout mode for a period of time.
invalidated Fires when the IconCaptcha invalidated itself after a period of time without user interaction.
reset Fires when the a captcha instance was manually reset using the reset function.
success Fires when the user selected the correct icon.
error Fires when the user selected the incorrect icon.

Reset a captcha instance

It is possible to manually reset a specific captcha instance, and even every captcha instance present on the webpage.

To do so, simply call the IconCaptcha.reset() function from within your custom JavaScript code. This will reset every rendered captcha instance on the page. If you only wish to target a specific instance, pass the instance identifier (a number, going up from 1 to the maximum number of instances rendered on the page) to the reset function: IconCaptcha.reset(1).

Custom Themes

To register a custom CSS theme, you must register it in the IconCaptcha PHP options before it can be properly used. For each custom theme, an icon color and icon separator color must be picked. The example code below shows the custom theme black being registered.

<?php
    IconCaptcha::options([
        ...
        'themes' => [
            'black' => [
                'icons' => 'light', // Which icon type should be used: light or dark.
                'color' => [20, 20, 20], // RGB value of the icon separator border color.
            ]
        ],
        ...
    ]);
?>

By default, the icon theme colors light and dark are available. The icons can be found in the dist/icons/ folder of the Front-End package, or the assets/icons/ folder of the PHP package. If you wish to add any other icon color, you must copy all the icons from either the light or dark folder to a new folder, and use photo editing software - such as Adobe Photoshop - to convert the copied icons into your desired color.

For reference:

  • Captcha theme light and legacy-light use the light icon color, which use black icons.
  • Captcha theme dark and legacy-dark use the dark icon color, which use white icons.