An invisible reCAPTCHA package for Laravel, Lumen, CI or native PHP.

Overview

Invisible reCAPTCHA

php-badge packagist-badge Total Downloads travis-badge

invisible_recaptcha_demo

Why Invisible reCAPTCHA?

Invisible reCAPTCHA is an improved version of reCAPTCHA v2(no captcha). In reCAPTCHA v2, users need to click the button: "I'm not a robot" to prove they are human. In invisible reCAPTCHA, there will be not embed a captcha box for users to click. It's totally invisible! Only the badge will show on the buttom of the page to hint users that your website is using this technology. (The badge could be hidden, but not suggested.)

Notice

  • The master branch doesn't support multi captchas feature, please use multi-forms branch if you need it. (Most of the time you are misusing recaptcha when you try to put multiple captchas in one page.)

Installation

composer require albertcht/invisible-recaptcha

Laravel 5

Setup

Add ServiceProvider to the providers array in app/config/app.php.

AlbertCht\InvisibleReCaptcha\InvisibleReCaptchaServiceProvider::class,

It also supports package discovery for Laravel 5.5.

Configuration

Before you set your config, remember to choose invisible reCAPTCHA while applying for keys. invisible_recaptcha_setting

Add INVISIBLE_RECAPTCHA_SITEKEY, INVISIBLE_RECAPTCHA_SECRETKEY to .env file.

// required
INVISIBLE_RECAPTCHA_SITEKEY={siteKey}
INVISIBLE_RECAPTCHA_SECRETKEY={secretKey}

// optional
INVISIBLE_RECAPTCHA_BADGEHIDE=false
INVISIBLE_RECAPTCHA_DATABADGE='bottomright'
INVISIBLE_RECAPTCHA_TIMEOUT=5
INVISIBLE_RECAPTCHA_DEBUG=false

There are three different captcha styles you can set: bottomright, bottomleft, inline

If you set INVISIBLE_RECAPTCHA_BADGEHIDE to true, you can hide the badge logo.

You can see the binding status of those catcha elements on browser console by setting INVISIBLE_RECAPTCHA_DEBUG as true.

Usage

Before you render the captcha, please keep those notices in mind:

  • render() or renderHTML() function needs to be called within a form element.
  • You have to ensure the type attribute of your submit button has to be submit.
  • There can only be one submit button in your form.
Display reCAPTCHA in Your View
{!! app('captcha')->render() !!}

// or you can use this in blade
@captcha

With custom language support:

{!! app('captcha')->render('en') !!}

// or you can use this in blade
@captcha('en')
Usage with Javascript frameworks like VueJS:

The render() process includes three distinct sections that can be rendered separately incase you're using the package with a framework like VueJS which throws console errors when <script> tags are included in templates.

You can render the polyfill (do this somewhere like the head of your HTML:)

{!! app('captcha')->renderPolyfill() !!}
// Or with blade directive:
@captchaPolyfill

You can render the HTML using this following, this needs to be INSIDE your <form> tag:

{!! app('captcha')->renderCaptchaHTML() !!}
// Or with blade directive:
@captchaHTML

And you can render the neccessary <script> tags including the optional language support by using:

// The argument is optional.
{!! app('captcha')->renderFooterJS('en') !!}

// Or with blade directive:
@captchaScripts
// blade directive, with language support:
@captchaScripts('en')
Validation

Add 'g-recaptcha-response' => 'required|captcha' to rules array.

$validate = Validator::make(Input::all(), [
    'g-recaptcha-response' => 'required|captcha'
]);

CodeIgniter 3.x

set in application/config/config.php :

$config['composer_autoload'] = TRUE;

add lines in application/config/config.php :

$config['recaptcha.sitekey'] = 'sitekey'; 
$config['recaptcha.secret'] = 'secretkey';
// optional
$config['recaptcha.options'] = [
    'hideBadge' => false,
    'dataBadge' => 'bottomright',
    'timeout' => 5,
    'debug' => false
];

In controller, use:

$data['captcha'] = new \AlbertCht\InvisibleReCaptcha\InvisibleReCaptcha(
    $this->config->item('recaptcha.sitekey'),
    $this->config->item('recaptcha.secret'),
    $this->config->item('recaptcha.options'),
);

In view, in your form:

<?php echo $captcha->render(); ?>

Then back in your controller you can verify it:

$captcha->verifyResponse($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']);

Without Laravel or CodeIgniter

Checkout example below:

<?php

require_once "vendor/autoload.php";

$siteKey = 'sitekey';
$secretKey = 'secretkey';
// optional
$options = [
    'hideBadge' => false,
    'dataBadge' => 'bottomright',
    'timeout' => 5,
    'debug' => false
];
$captcha = new \AlbertCht\InvisibleReCaptcha\InvisibleReCaptcha($siteKey, $secretKey, $options);

// you can override single option config like this
$captcha->setOption('debug', true);

if (!empty($_POST)) {
    var_dump($captcha->verifyResponse($_POST['g-recaptcha-response'], $_SERVER['REMOTE_ADDR']));
    exit();
}

?>

<form action="?" method="POST">
    <?php echo $captcha->render(); ?>
    <button type="submit">Submit</button>
</form>

Take Control of Submit Function

Use this function only when you need to take all control after clicking submit button. Recaptcha validation will not be triggered if you return false in this function.

_beforeSubmit = function(e) {
    console.log('submit button clicked.');
    // do other things before captcha validation
    // e represents reference to original form submit event
    // return true if you want to continue triggering captcha validation, otherwise return false
    return false;
}

Customize Submit Function

If you want to customize your submit function, for example: doing something after click the submit button or changing your submit to ajax call, etc.

The only thing you need to do is to implement _submitEvent in javascript

_submitEvent = function() {
    console.log('submit button clicked.');
    // write your logic here
    // submit your form
    _submitForm();
}

Here's an example to use an ajax submit (using jquery selector)

_submitEvent = function() {
    $.ajax({
        type: "POST",
        url: "{{route('message.send')}}",
         data: {
            "name": $("#name").val(),
            "email": $("#email").val(),
            "content": $("#content").val(),
            // important! don't forget to send `g-recaptcha-response`
            "g-recaptcha-response": $("#g-recaptcha-response").val()
        },
        dataType: "json",
        success: function(data) {
            // success logic
        },
        error: function(data) {
            // error logic
        }
    });
};

Example Repository

Repo: https://github.com/albertcht/invisible-recaptcha-example

This repo demonstrates how to use this package with ajax way.

Showcases

Credits

Support on Beerpay

Hey dude! Help me out for a couple of 🍻 !

Beerpay Beerpay

Comments
  • INVISIBLE_RECAPTCHA_DEBUG=true doesn't seem to work

    INVISIBLE_RECAPTCHA_DEBUG=true doesn't seem to work

    Currently on my site the invisible recaptcha is not working on my registration page, and upon submit, the recaptca is failing and I have INVISIBLE_RECAPTCHA_DEBUG=true but don't see any logs inside of laravel.log or console errors. Where does this debug show up?

    help wanted question 
    opened by david-j-davis 21
  • Uncaught Error: The bind parameter must be an element or id recaptcha__en.js:380

    Uncaught Error: The bind parameter must be an element or id recaptcha__en.js:380

    <div id="_g-recaptcha"></div>
    <div class="g-recaptcha" data-sitekey="x" data-bind="send-btn" data-callback="_submitForm"></div><script src="https://www.google.com/recaptcha/api.js" async defer></script>
    
    <script>var _submitForm,_captchaForm,_captchaSubmit;</script>
    <script>
    window.onload=function(){_captchaForm=document.querySelector("#_g-recaptcha").closest("form");
    _captchaSubmit=_captchaForm.querySelector('[type=submit]');
    _submitForm=function(){if(typeof _submitEvent==="function"){_submitEvent();grecaptcha.reset();}else{_captchaForm.submit();
    }}}
    </script>
    
    this is the HTML generated by  {!! app('captcha')->render() !!}
    

    the g-recaptcha-response in $_REQUEST comes back empty as well.

    opened by arminneman 19
  • Problem with multiform invisible recaptcha

    Problem with multiform invisible recaptcha

    Uncaught TypeError: $(...).tooltip is not a function at HTMLDocument. (skyweb.frame.js:32) at j (jquery.min.js:2) at Object.fireWith [as resolveWith] (jquery.min.js:2) at Function.ready (jquery.min.js:2) at HTMLDocument.J (jquery.min.js:2)

    When the multiform invisible recaptcha is used, I get this error :/

    opened by babalubas090 16
  • Laravel 8.x Compatibility

    Laravel 8.x Compatibility

    This is an automated pull request from Shift to update your package code and dependencies to be compatible with Laravel 8.x.

    Before merging, you need to:

    • Checkout the l8-compatibility branch
    • Review all comments for additional changes
    • Thoroughly test your package

    If you do find an issue, please report it by commenting on this PR to help improve future automation.

    opened by laravel-shift 13
  • Add partial/split render methods to allow usage with restrictive javascript frameworks.

    Add partial/split render methods to allow usage with restrictive javascript frameworks.

    This request just splits out the render method into completely optional separate methods and directives which can be used to pull the script tags out of the main <form> - allowing you to use this with VueJS and any other HTML template based Javascript framework that might restrict script tags in the template.

    opened by danmatthews 9
  • Uncaught Error: Missing required parameters: sitekey

    Uncaught Error: Missing required parameters: sitekey

    Console error:

    Uncaught Error: Missing required parameters: sitekey at new es (recaptcha__en.js:402) at new ys (recaptcha__en.js:408) at Ks (recaptcha__en.js:416) at recaptcha__en.js:416 at Array.forEach () at Ls (recaptcha__en.js:416) at vs (recaptcha__en.js:421) at ws (recaptcha__en.js:408) at recaptcha__en.js:423 at recaptcha__en.js:431

    My INVISIBLE_RECAPTCHA_SITEKEY and INVISIBLE_RECAPTCHA_SECRETKEY env variables are set.

    opened by JamesPoel 8
  • Multiple re-catpchas on page throws ERRORS - ReCAPTCHA placeholder element must be empty

    Multiple re-catpchas on page throws ERRORS - ReCAPTCHA placeholder element must be empty

    Hello, thank you for your cool package.

    I have issue with multiple re captchas on single page. I have 3 forms, login, registration and reset password.

    2 of them hidde, when you click button, appears form we need. I do not want to do this with ajax or async loading forms. Because user can loop it and do bad stuff to server, loading forms. So i think this is bad practice to do like that.

    When i use @captcha($lang = null) on all my 3 forms, it show 2 error for other 2 form. So only 1 re-captcha works, other to not.

    ERROR Uncaught Error: ReCAPTCHA placeholder element must be empty at nr (recaptcha__ru.js:473) at recaptcha__ru.js:478 at c (recaptcha__ru.js:468)

    How to fix it? Or i should try visible captcha? Will it work?

    opened by PhPPgAdminBug 8
  • Issue with multiple forms using captcha in the same page

    Issue with multiple forms using captcha in the same page

    Hello, I have multiple forms in the same page that uses invisible reCaptcha the issue with this library is that when rendering the captcha using

    {!! app('captcha')->render(); !!}
    

    It creates a _g-recaptcha id

     <div id="_g-recaptcha"></div>
    

      and also loads https://www.google.com/recaptcha/api.js script

    if you could simple change _g-recaptcha to use a class and load the script once with some other way like app('captcha')->init(). Multi form support should work perfectly.

    For the time being i will try to do it manually in the frontend without using app('captcha')->render() method, but i hope that you will support this in the future.

    duplicate 
    opened by martinsce 7
  • How to use multi-forms

    How to use multi-forms

    Hi, I've seen your multi-form branch, but I'd like to know how to use it correctly. I have 1 form that always appears in the footer of the website (newsletter), and sometimes the contact form appears on other pages.

    In that case, how do I call the recaptcha? Can I use "@captcha()" in each form, or should I encode JS for face form?

    help wanted question 
    opened by garbinmarcelo 6
  • INVISIBLE_RECAPTCHA_BADGEHIDE does not work

    INVISIBLE_RECAPTCHA_BADGEHIDE does not work

    Hello There,

    I was trying to hide the badge on the bottom right but it didnt work like i wanted it to. Here is my .env file.

    schermafbeelding 2018-02-12 om 22 39 19

    And this is what i see in my frontend.

    schermafbeelding 2018-02-12 om 22 40 02

    In blade im using this.

    schermafbeelding 2018-02-12 om 22 46 25

    The HTML you output is correct look at this.

    schermafbeelding 2018-02-12 om 22 50 23

    Im not 100% sure how but when i inspect the badge winch has class .grecaptcha-badge indeed. The style from the class is never applied to it. I don't understand why because the i have no other classes named .grecaptcha-badge and i don't ajax load any html or css code for styles and the captcha is loaded with the page by default.

    Just thinking might it be a race condition where the class in css is defined but the object is rendered via javascript later. It should not be i know because the css is defined before the badge is rendered but it still comes to mind ..

    OR !! When the javascript renders it importants and other css rule show the badge and that will over write your display: none rule. That must be it i think .. You can fix that with javascript and maybe add a section to your views and tell the users to yield the javascript code in the footer. Im going to test this now ..

    Okey i got most working now with css but it still has a border like this

    iframe[src^="https://www.google.com/recaptcha/api2/anchor"] {
      visibility: hidden;
    }
    

    This hides the badge BUT does not hide its border .. we need to investigate more.

    I just figured it out to hide both the iframe internals and the border you need this javascript code. After the document loaded (so the iframe == the loaded as well)..

    We need to do the below code because google adds inline style properties to the .grecaptcha-badge element. We could do without it if a stylesheet would be loaded after the DOM is ready but right now we cant so we need some javascript (so sad).

    document.addEventListener('DOMContentLoaded', function () {
      let box = document.querySelector('.grecaptcha-badge');
      box.style.boxShadow = 'none'
    });
    

    This will hide the google Recaptcha box 100%. It might be as well that you also set a display as none (or visibilty:hidden) as that value on document ready. i Think the code evaluated singe you wrote it.. So its one ore the other both do it via javascript or half on half ..

    schermafbeelding 2018-02-12 om 23 52 14

    Thanks for listening .. sleep well have a good day ..

    Johnny Mast...

    opened by johnnymast 6
  • INVISIBLE_RECAPTCHA_BADGEHIDE not hiding badge

    INVISIBLE_RECAPTCHA_BADGEHIDE not hiding badge

    Hi, it seems the INVISIBLE_RECAPTCHA_BADGEHIDE env is doing nothing.

    my .env:

    INVISIBLE_RECAPTCHA_SITEKEY=my_key
    INVISIBLE_RECAPTCHA_SECRETKEY=my_key
    INVISIBLE_RECAPTCHA_BADGEHIDE=true
    INVISIBLE_RECAPTCHA_DEBUG=false
    

    my form:

    `
    /* ... */
    {!! app('captcha')->render(LaravelLocalization::getCurrentLocale()) !!}
    /* ... */
    <button type="submit" class="btn btn-primary btn-rounded">
        submit
    </button>
    

    the result: capture d ecran 2018-01-25 a 09 10 24

    opened by hedii 6
  • Full support for Multi form recaptcha

    Full support for Multi form recaptcha

    Could we add full support for multiple form Recaptcha on this?

    In the docs, I've read it saying that most of the time if you need Recaptcha more than once on a single page, you're doing it wrong. That can't be further from the truth.

    Explain then how you go around with a login page, that accepts email and password and is validated by Recaptcha, and at the same time, has a button on the side of that same page. And that button opens a feedback form, also validated by Recaptcha.

    Right now, I do see some dev support for multiple Recaptcha on the page, but it looks like it can only be done through jquery.

    Any advice would be appreciated.

    opened by timbogdanov 0
  • The g-recaptcha-response field is required

    The g-recaptcha-response field is required

    I see the badge logo on bottom right corner but the validation always fails. Also got "g-recaptcha-response": null when debug the request using request()->all() I'm using the test key as stated here: https://developers.google.com/recaptcha/docs/faq#id-like-to-run-automated-tests-with-recaptcha.-what-should-i-do

    Laravel v6.20.x albertcht/invisible-recaptcha v1.9.7

    opened by handhikadj 0
  • CWE-79 - Reflected Cross Site scripting vulnerability at /InvisibleRecaptcha.php

    CWE-79 - Reflected Cross Site scripting vulnerability at /InvisibleRecaptcha.php

    Hey, I'd like to request you to issue a CVE for this pull request.

    Summary

    As I'm doing security research during my bug bounty activities I stumbled upon an issue with a client that uses invisible-recaptcha

    specifically speaking, the issue is within the "ac" parameter

    As I discovered the vulnerability during my BlackBox approach, I decided to report it in this repo and to see the white box root cause of the matter.

    The url of my proof of concept looked like the following:

    invisibleRecaptcha?sitekey=XXXXXX&lang=XX&label=XXX&ac=</script><a%20href=javascript:alert(document.domain)>hi</a>
    

    The payload I used was to escape the javascript context that the input was injected into and insert my own Cross Site Scripting code.

    Screen Shot 2021-10-03 at 17 28 35

    opened by NagliNagli 0
  • lazy loading option

    lazy loading option

    Hi, please take a look at the lazy load option.

    captcha['options']['lazyLoad'] = env('INVISIBLE_RECAPTCHA_LAZYLOAD', false)

    This feature delay loading recapcha for better google pagespeed rank.

    opened by zherdev-artem 0
  • Conflict with VueJS

    Conflict with VueJS

    Hi, i saw you added some optimizations for VueJS which works nicely, but i found a minor bug.

    Follow these steps in Laravel app with VueJS

    1. Implement recaptcha with your VueJS guidelines (polyfill part to head, html in form and script part placed outside of Vue wrapper element)
    2. DISABLE recaptcha badge in config

    Now just load page and you can see that Vue framework throw and error that you have style placed inside your Vue part. That is because @captchaHTML actually also include style with display:none on the badge.

    You can easily fix this by placing style tag in the @captchaPolyfill and not @captchaHTML.

    Many thanks for great package and have a nice day!

    opened by desthercz 0
Releases(v1.9.7)
Owner
Albert Chen
Albert Chen
A Native PHP MVC With Auth. If you will build your own PHP project in MVC with router and Auth, you can clone this ready to use MVC pattern repo.

If you will build your own PHP project in MVC with router and Auth, you can clone this ready to use MVC pattern repo. Auth system is implemented. Works with bootstrap 5. Composer with autoload are implemented too for future composer require.

null 2 Jun 6, 2022
Easy, native Laravel user authorization.

An easy, native role / permission management system for Laravel. Index Installation Migration Customization Model Customization Usage Checking Permiss

DirectoryTree 5 Dec 14, 2022
An OAuth 2.0 bridge for Laravel and Lumen [DEPRECATED FOR LARAVEL 5.3+]

OAuth 2.0 Server for Laravel (deprecated for Laravel 5.3+) Note: This package is no longer maintaned for Laravel 5.3+ since Laravel now features the P

Luca Degasperi 2.4k Jan 6, 2023
🔐 JSON Web Token Authentication for Laravel & Lumen

Documentation Documentation for 1.* here For version 0.5.* See the WIKI for documentation. Supported by Auth0 If you want to easily add secure authent

Sean Tymon 10.7k Dec 31, 2022
Making Laravel Passport work with Lumen

lumen-passport Making Laravel Passport work with Lumen A simple service provider that makes Laravel Passport work with Lumen Dependencies PHP >= 5.6.3

Denis Mysenko 651 Dec 1, 2022
JWT auth for Laravel and Lumen

JWT Artisan Token auth for Laravel and Lumen web artisans JWT is a great solution for authenticating API requests between various services. This packa

⑅ Generation Tux ⑅ 141 Dec 21, 2022
🔐 JSON Web Token Authentication for Laravel & Lumen

Credits This repository it a fork from original tymonsdesigns/jwt-auth, we decided to fork and work independent because the original one was not being

null 490 Dec 27, 2022
🔑 Simple Keycloak Guard for Laravel / Lumen

Simple Keycloak Guard for Laravel / Lumen This package helps you authenticate users on a Laravel API based on JWT tokens generated from Keycloak Serve

Robson Tenório 277 Jan 3, 2023
Authentication REST-API built with Lumen PHP Framework

Authentication REST-API built with Lumen PHP Framework Laravel Lumen is a stunningly fast PHP micro-framework for building web applications with expre

Hüseyin Yağlı 1 Oct 12, 2021
HTTP Basic Auth Guard for Lumen 5.x

HTTP Basic Auth Guard HTTP Basic Auth Guard is a Lumen Package that lets you use basic as your driver for the authentication guard in your application

Christopher Lass 40 Nov 11, 2022
A Laravel 5 package for OAuth Social Login/Register implementation using Laravel socialite and (optionally) AdminLTE Laravel package

laravel-social A Laravel 5 package for OAuth Social Login/Register implementation using Laravel socialite and (optionally) AdminLTE Laravel package. I

Sergi Tur Badenas 42 Nov 29, 2022
PHP package built for Laravel 5.* to easily handle a user email verification and validate the email

jrean/laravel-user-verification is a PHP package built for Laravel 5.* & 6.* & 7.* & 8.* to easily handle a user verification and validate the e-mail.

Jean Ragouin 802 Dec 29, 2022
via this package you can push notifications to [ Facebook , Twitter , Telegram , Linkedin ] ( Laravel )

Push To Social [ Facebook , Twitter , Telegram , Linkedin ] via this package you can push notifications to [ Facebook , Twitter , Telegram , Linkedin

Peter Tharwat 29 Nov 4, 2022
Dynamic ACL is a package that handles Access Control Level on your Laravel Application.

Dynamic ACL Dynamic ACL is a package that handles Access Control Level on your Laravel Application. It's fast to running and simple to use. Install an

yasin 8 Jul 31, 2022
Powerful package for handling roles and permissions in Laravel 5

Roles And Permissions For Laravel 5 Powerful package for handling roles and permissions in Laravel 5 (5.1 and also 5.0). Installation Composer Service

Roman Bičan 1.2k Dec 17, 2022
Laravel package to easily login as other users during development.

A Laravel 5.4 utility package to enable developers to log in as other users during development. Installation To install the package, simply follow the

VIA Creative 555 Jan 8, 2023
PermissionsMakr is a Laravel package that will help any developer to easily manage the system's users permissions

PermissionsMakr is a Laravel package that will help any developer to easily manage the system's users permissions

Alvarium Digital 3 Nov 30, 2021
A Powerful package for handling roles and permissions in Laravel with GUI.

Laravel Roles A Powerful package for handling roles and permissions in Laravel. Supports Laravel 5.3, 5.4, 5.5, 5.6, 5.7, 5.8, 6.0, 7.0, and 8.0+. Tab

Jeremy Kenedy 827 Jan 1, 2023
This package helps you to associate users with permissions and permission groups with laravel framework

Laravel ACL This package allows you to manage user permissions and groups in a database, and is compatible with Laravel v5.8 or higher. Please check t

Mateus Junges 537 Dec 28, 2022