GithubHelp home page GithubHelp logo

ryandadeng / laravel-google-recaptcha-v3 Goto Github PK

View Code? Open in Web Editor NEW
263.0 6.0 40.0 377 KB

It's probably the best Laravel Package for Google reCAPTCHA v3. Vue component supported.

License: MIT License

PHP 92.04% Vue 4.22% Blade 3.74%
google-recaptcha recaptcha-v3 laravel-recaptcha googlerecaptcha google-recaptcha-v3 laravel-google-recaptcha recaptcha-v3-laravel laravel-recaptcha-v3 recaptcha recaptcha-laravel

laravel-google-recaptcha-v3's Introduction

Laravel Package for Google reCAPTCHA V3

Latest Version on Packagist Total Downloads Coverage Status Build StyleCI

A star would be a nice encouragement. ^.^

Latest features:

  • Refresh Ajax supported
  • Content security policy supported
  • Multi lang supported
  • Vue component supported
  • Background mode supported

If you want to use v2, please go to: https://github.com/RyanDaDeng/laravel-google-recaptcha-v2

If you only need to use Vue component, feel free to copy it.

Table of Contents

  1. Installation
  2. Configurations
  3. Facade Usage
  4. Blade Usage
  5. Ajax Usage
  6. Vue Usage
  7. Validation
  8. Advanced Usage
  9. Contributors

Demo code: https://github.com/RyanDaDeng/laravel-google-recaptcha-v3/wiki/Simple-Demo

DEMO

Invisible - hidden

Inline

Corner

Description

Google reCAPTCHA v3 is a new mechanism to verify whether the user is bot or not.

reCAPTCHA v3 is intended for power users, site owners that want more data about their traffic, and for use cases in which it is not appropriate to show a challenge to the user.

For example, a registration page might still use reCAPTCHA v2 for a higher-friction challenge, whereas more common actions like sign-in, searches, comments, or voting might use reCAPTCHA v3.

Please check Google site: https://developers.google.com/recaptcha/docs/faq

Features

  • High Test coverage, safe and easy to use
  • Score Comparision
  • Support invisible, corner and inline badge style
  • Support reCAPTCHA to run on every page
  • Support multiple actions to be placed on the same page
  • Support custom implementation on config interface
  • Support custom implementation on request method interface
  • Fully supported Vue component
  • IP skip list supported

Requirement

This package requires the following dependencies:

  • Laravel >= 5.x

  • If you want to use Validation Class your Laravel version needs to be >= 5.5

  • php > 5

  • Please ensure that you have read basic information from Google reCAPTCHA v3.

Installation

Demo code: https://github.com/RyanDaDeng/laravel-google-recaptcha-v3/wiki/Simple-Demo

Via Composer

        $ composer require timehunter/laravel-google-recaptcha-v3 "~2.5" -vvv

If your Laravel framework version <= 5.4, please register the service provider under your config file: /config/app.php, otherwise please skip it.

'providers'=[
    ....,
    TimeHunter\LaravelGoogleReCaptchaV3\Providers\GoogleReCaptchaV3ServiceProvider::class
]

And also

'aliases'=[
     ....,
     'GoogleReCaptchaV3'=> TimeHunter\LaravelGoogleReCaptchaV3\Facades\GoogleReCaptchaV3::class
 ]

If your Laravel framework version is >= 5.5, just run the following command to publish config.

$ php artisan vendor:publish --provider="TimeHunter\LaravelGoogleReCaptchaV3\Providers\GoogleReCaptchaV3ServiceProvider" --tag=googlerecaptchav3.config

For vue component:

$ php artisan vendor:publish --provider="TimeHunter\LaravelGoogleReCaptchaV3\Providers\GoogleReCaptchaV3ServiceProvider" --tag=googlerecaptchav3.vuejs

After installation, you should see a googlerecaptchav3.php in your app/config folder, and vue component under js/components/googlerecaptchav3 folder.

For multi lang:

$ php artisan vendor:publish --provider="TimeHunter\LaravelGoogleReCaptchaV3\Providers\GoogleReCaptchaV3ServiceProvider" --tag=googlerecaptchav3.lang

A lang folder will be created under /resources/lang/vendor/GoogleReCaptchaV3/*

Configurations

Setting up your Google reCAPTCHA details in config file

Please register all details in config for host_name, site_key, secret_key and site_verify_url.

Register credentials in .env:

RECAPTCHA_V3_SECRET_KEY=
RECAPTCHA_V3_SITE_KEY=

Specify your Score threshold and action in 'setting', e.g.

      'setting' =  [
          [
                'action' => 'contact_us', // Google reCAPTCHA required paramater
                'threshold' => 0.2, // score threshold
                'score_comparison' => false // if this is true, the system will do score comparsion against your threshold for the action
            ],
            [
                'action' => 'signup',
                'threshold' => 0.2,
                'score_comparison' => true
            ],
        ]

Note: if you want to enable Score Comparision, you also need to enable is_score_enabled to be true.

        ...
        'is_score_enabled' = true
        ...

For score comparision, all actions should be registered in googlerecaptchav3 config file under 'setting' section.

For more details please check comments in config file.

Facade Usage

You can directly use registered facade service by calling the following methods.

  • setAction() is optional only if you want to verify if the action is matched.
  • verifyResponse() which accepts the token value from your form. This returns Google reCAPTCHA Response object.
  • setScore() is optional only if you want to manually verify the score.

Example Usage

   GoogleReCaptchaV3::setAction($action)->verifyResponse($value,$ip = null);
   GoogleReCaptchaV3::verifyResponse($value,$ip)->getMessage();
   GoogleReCaptchaV3::verifyResponse($value)->isSuccess();
   GoogleReCaptchaV3::verifyResponse($value)->toArray();
   GoogleReCaptchaV3::verifyResponse(
                         $request->input('g-recaptcha-response'),
                         $request->getClientIp()
                         )
                      ->getMessage()
   GoogleReCaptchaV3::setAction($action)->verifyResponse($value)->isSuccess();

If you manually assign a value to setScore($score), the code will fully skip your config file and force to check the score.

   GoogleReCaptchaV3::setScore($score)
                    ->setAction($action)
                    ->verifyResponse(
                        $request->input('g-recaptcha-response'),
                        $request->getClientIp()
                        )
                    ->getMessage()

Validation Class (Only support Laravel >= 5.5)

You can use provided Validation object to verify your reCAPTCHA.

   use TimeHunter\LaravelGoogleReCaptchaV3\Validations\GoogleReCaptchaV3ValidationRule;
   $rule = [
            'g-recaptcha-response' => [new GoogleReCaptchaV3ValidationRule('action_name')]
        ];
  • $actionName: if its NULL, the package won't verify action with google response.

Blade Usage

Display reCAPTCHA v3

Add Google API script

Include the API script at the bottom of your layout page

  {!!  GoogleReCaptchaV3::init() !!}
Consent Security Policy - Nonce

To add a nonce for content security, pass a params array with your pages nonce.

  {!!  GoogleReCaptchaV3::init([
    'nonce' => nonce(),
  ]) !!}

Running script on every page (optional)

It's recommended to include reCAPTCHA v3 on every page which can help you get the most context about interactions for analytics. You just need to enable the config:

   ...
  'background_badge_display' => true, // if false, the badge will be invisible, if true the badge shows at bottom right.
  'background_mode' => false, // if true, the script will run on every page (ensure that GoogleReCaptchaV3::init() is placed on layout or homepage)
   ...

If the page has not detected any Action or duplicate google script, the background mode will be enabled.

Form & Action

There are three methods to populate the reCAPTCHA within the form.

  • render() and renderOne() can be placed in anywhere but before init()
  • renderField() needs always to be placed within your form.

Method one - render():

[
    $id=>$action , $id=>$action ...
]

{!!  GoogleReCaptchaV3::render(['contact_us_id'=>'contact_us', 'signup_id'=>'signup']) !!}
<form method="POST" action="/verify">
    <div id="contact_us_id"></div> // add div with id
    <input type="submit" value="submit">
</form>


<form method="POST" action="/verify">
    <div id="signup_id"></div>
    <input type="submit" value="submit">
</form>

{!!  GoogleReCaptchaV3::render(['contact_us_id'=>'contact_us', 'signup_id'=>'signup']) !!}

Method two - renderOne():

GoogleReCaptchaV3::renderOne($id,$action);

{!!  GoogleReCaptchaV3::renderOne('contact_us_id','contact_us') !!}
<form method="POST" action="/verify">
    <div id="contact_us_id"></div> // add div with id
    <input type="submit" value="submit">
</form>

{!!  GoogleReCaptchaV3::renderOne('contact_us_id','contact_us') !!}

Method three - renderField():

GoogleReCaptchaV3::renderField($id,$action,$class,$style)

{!! GoogleReCaptchaV3::renderField('contact_us_id','contact_us_action') !!}
<form method="POST" action="/verify">
   {!!  GoogleReCaptchaV3::renderField('contact_us_id','contact_us_action') !!}
    <input type="submit" value="submit">
</form>

Badge Display for Form & Action

If your settings were not reflected, please run php artisan config:cache to clear cache.

Inline

  1. Go to config file, and set
    [
        ...
        'inline' => true
        ...
    ]
  1. Badge will be displayed as inline format within the form.

Invisible

  1. Set inline as true as well
  2. Modify your div with style display:none
  3. Refer to Google official site: https://developers.google.com/recaptcha/docs/faq , you need to include the following text:
   This site is protected by reCAPTCHA and the Google
       <a href="https://policies.google.com/privacy">Privacy Policy</a> and
       <a href="https://policies.google.com/terms">Terms of Service</a> apply.

Corner

  1. Set inline as false
  2. Your badge will be shown in the bottom right side.

Custom

  1. Set inline as true
  2. Do Styling/CSS on its div element

Ajax Usage - Refresh reCAPTCHA Response

The package provides two handy Javascript functions for you to get recaptcha response and refresh recaptcha as needed.

  • refreshReCaptchaV3(fieldId,actionName) - this function will reset the response whenever your ajax response is returned.

  • getReCaptchaV3Response - this function helps you to get recaptcha response by id

For example:

       <script>
            $("#test").click(function (e) {
                e.preventDefault();
                $.ajax({
                    type: 'POST',
                    url: '/verify',
                    data: {
                        'g-recaptcha-response':getReCaptchaV3Response('contact_id')
                    },
                    success: function (data) {
                        refreshReCaptchaV3('contact_id','contact');
                    },
                    error: function(err){
                        refreshReCaptchaV3('contact_id','contact');
                    }
                });
            });
      </script>

Vue Usage (Package version >= 2.2.0)

The package provides a lightweight vue component. You need to publish the vue component before playing around it.

Step 1 Publish vue component:

$ php artisan vendor:publish --provider="TimeHunter\LaravelGoogleReCaptchaV3\Providers\GoogleReCaptchaV3ServiceProvider" --tag=googlerecaptchav3.vuejs

The file will be created under js/components/googlerecaptchav3/GoogleReCaptchaV3.vue, you have full control and modification ability on this file.

Step 2 Import vue component and Register reCAPTCHA v3 SiteKey

A BIG thanks to @Fluxlicious who improved the vue component.

The Blade way is no longer useful if you use Vue. We need to manage to assign site key by ourselves. The component supports props below:

Supported: siteKey, id, inline and action, check the original file to see the details.

<google-re-captcha-v3
  v-model="gRecaptchaResponse"
  ref="captcha"
  site-key="Your Site Key String Here"
  id="contact_us_id"
  inline
  action="contact_us"
></google-re-captcha-v3>

There are two ways you can bind site key to the component.

Use prop

<template>
    <div>
        <form @submit.prevent="submit">
            <div>
                <google-re-captcha-v3
                  v-model="form.gRecaptchaResponse"
                  ref="captcha"
                  :site-key="mySiteKeyVariable"
                  id="contact_us_id"
                  inline
                  action="contact_us"
                ></google-re-captcha-v3>
            </div>
            <button type="submit">Submit</button>
        </form>
    </div>
</template>
<script>
    import GoogleReCaptchaV3 from '../../components/googlerecaptchav3/GoogleReCaptchaV3';
    // location might be diff to your case, ensure that your component location is right

    export default {
        components: {
            GoogleReCaptchaV3
        },
        data() {
            return {
                form: {
                    gRecaptchaResponse: null
                },
                mySiteKeyVariable: 'Your Site Key String',
            }
        },
        methods: {
            submit() {
                axios.post('/verify', this.form).then(
                    response => {
                        this.$refs.captcha.execute(); // every time you submit, the reCAPTCHA token needs to be refreshed
                    }
                ).catch(
                    error => {
                        this.$refs.captcha.execute(); // every time you submit, the reCAPTCHA token needs to be refreshed
                    });
            }
        }
    }
</script>

Please remember to refresh token every time you submit the form if needed:

 this.$refs.captcha.execute();

or Add site key directly into GoogleReCaptchaV3 component

Alternatively, I believe most of cases your site key will never be changed, so you could just modify the original published component to have sitekey hard-coded in.

For instance, open published file and find code below:

        ....
        siteKey: {
                  type: String,
                  required: false, // set to true if you don't want to store the siteKey in this component
                  default: 'Your Site Key Here' // set siteKey here if you want to store it in this component
              },
       ....

Advanced Usage

Custom implementation on Config

For some users, they might store the config details in their own storage e.g database. You can create your own class and implement:

TimeHunter\LaravelGoogleReCaptchaV3\Interfaces\ReCaptchaConfigV3Interface

Remember to register it in your own service provider

     $this->app->bind(
                ReCaptchaConfigV3Interface::class,
                YourOwnCustomImplementation::class
            );

Custom implementation on Request method

The package has two default options to verify: Guzzle and Curl, if you want to use your own request method, You can create your own class and implement

TimeHunter\LaravelGoogleReCaptchaV3\Interfaces\RequestClientInterface

Remember to register it in your own service provider

     $this->app->bind(
                RequestClientInterface::class,
                YourOwnCustomImplementation::class
            );

Contributors

Thank you for the following contributors, You guys are the BEST!

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

License

MIT. Please see the license file for more information.

laravel-google-recaptcha-v3's People

Contributors

alr2413 avatar demiurge-ash avatar fluxlicious avatar indianos avatar ldommer avatar luisrossi avatar quentinbontemps avatar ryandadeng avatar weisskpub avatar xalunda 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

laravel-google-recaptcha-v3's Issues

Missing-input-response

Extention of issue #40!

By using parts of the code in de demo file, I also get the error message missing-input-response, see image below.

I can't seem to get this to work, any help or tips?

image

Missing input response.

when i send call by blade, i have this problem. u know why ? 🀒

Missing input response.

Code Blade:
{!! GoogleReCaptchaV3::render(['contact_us_id'=>'quote']) !!}

config:

'setting' => [
    [
        'action' => 'quote',
        'threshold' => 0,
        'score_comparision' => false,
    ],
],

Controller:

    $this->request->validate([
        'g-recaptcha-response' => [new GoogleReCaptchaV3ValidationRule('quote')],
    ]);

Returning "Successfully passed" as error

Hi, sometime, only access in mobile, my users are getting "Successfully passed" as an error message.

My implementation is correct... It works at browser, but sometimes get this error in mobile.

And I don't know how to solve this.

It works for domain but not for its subdomains

I run the package on foo.localhost but it always says "Hostname does not match."

The host_name in config is set to "localhost"

When I change the host in config to "foo.localhost" it works

Issue with Validation class (Request) and function rules()

Hello friends,

My env : Laravel 8, PHP7.3, Vue.Js 2.0

I don't know what's wrong with that ... why he is waiting for a string ?

This my validation class

use Modules\Core\Http\Requests\Request;
use TimeHunter\LaravelGoogleReCaptchaV3\Validations\GoogleReCaptchaV3ValidationRule;

class RegisterRequest extends Request {

public function rules()
    {
        return [
            'first_name' => ['required'],
            'last_name' => ['required'],
            'email' => ['required', 'email', 'unique:users'],
            'phone' => ['required'],
            'password' => ['required', 'confirmed', 'min:6'],
            'g-recaptcha-response' => [new GoogleReCaptchaV3ValidationRule('register')],
            'privacy_policy' => ['accepted'],
        ];
    }
}

My blade file :

<div class="form-group p-t-5 d-flex  justify-content-between">
                        {!!  GoogleReCaptchaV3::renderField('grecaptcha','register') !!}
                        @error('g-recaptcha-response')
                        <span class="error-message">{{ $message }}</span>
                        @enderror
                    </div>

When I post I get this error :

TypeError
strpos(): Argument #1 ($haystack) must be of type string, TimeHunter\LaravelGoogleReCaptchaV3\Validations\GoogleReCaptchaV3ValidationRule given
http://192.168.1.169:8000/fr/register

With dd() I get the object :

TimeHunter\LaravelGoogleReCaptchaV3\Validations\GoogleReCaptchaV3ValidationRule {#2212 β–Ό
  #action: "register"
  #ip: null
  #message: null
}

Is the documentation is not full in the case we use validation class ?

Screenshot of Error 500
image

Thank you :)

Uncaught SyntaxError: Unexpected end of input

If I use Laravel HTMLMin

Uncaught SyntaxError: Unexpected end of input

var clientcontact_us_id; function onloadCallback() { if (document.getElementById('contact_us_id')) { clientcontact_us_id = grecaptcha.render('contact_us_action', { 'sitekey': '123', 'size': 'invisible', 'hl': 'ru', //'callback': function() {} }); grecaptcha.ready(function () { grecaptcha.execute(clientcontact_us_id, { action: 'contacts' }); }); } }

comment //'callback': function()
breaks the closing js statement

or change comment to /**/ or delete callback

Usage with Livewire

Thank you for creating this package. I am hoping to use this within a Livewire component and wondering whether there are any special considerations to take into account.

My use case is with a registration form. In my Livewire components blade file, I have:

<div>
    @push('footer-scripts')
    {!!  GoogleReCaptchaV3::init() !!}
    @endpush

    <form wire:submit.prevent="submit">
        {!!  GoogleReCaptchaV3::renderField('registration_id','registration') !!}
        
        <label class='text-white mb-2'>Name(*)</label>
        <input type="text" name="name" class='si_field' wire:model="name">

        {{-- remainder of registration fields here--}}
        
        <button>Submit</button>

    </form>
</div>

When the above is rendered, I can see the scripts from the package render (functions refreshReCaptchaV3(fieldId,action) and getReCaptchaV3Response(fieldId) but there is no entry for the api js from Google (i.e. <script src="https://www.google.com/recaptcha/api.js?render=my_site_key"></script>-) and the badge does not display.

Any pointers on the best way to use this package with Livewire? Apologies in advance if I have missed something very obvious!

Badge rules

Is it somehow possible to manage badge display rules ?

For instance, would be great to display it inline, just next to the submit button instead of on every page, in a fixed position.

Of course there is a legal aspect, I'm not sure what we can do or not....

Some topics on this :
https://stackoverflow.com/questions/53109566/how-do-i-hide-google-recaptcha-v3-from-my-site
https://stackoverflow.com/questions/50583284/how-do-you-set-the-badge-position-with-recaptcha-v3#answer-52557946

PS : You have an uncommented console.log() in your view.

Move site key and secret key to environment file

Hiya,

First thanks for this package love it to use in combination with the automatic validation check within a controller :-)!

Perhaps it would be nice if we could set the secret key and the site key inside our environment file. Sometimes you do not want those keys to be up in your repository. as simple change in the config file would to do this.

Want to send a PR when it's OK :-)

/verify route not being registered

After completing the installation instructions, any request, regardless of type, made to /verify results in a 404.

No cache, all cleared, running using VueJS validation
Laravel 6.5.2

Thanks in advance

Badge not rendering in the correct spot

I'm trying to use reCAPTCHA in multiple forms on a page and having the badge only displayed in the bottom right of the page so it doesn't need to be inline within the form.

I currently have the config values set:

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Default Request Method
    |--------------------------------------------------------------------------
    |
    | If not provided, will use curl as default.
    | Supported: "guzzle", "curl", if you want to use your own request method,
    | please read document.
    |
    */
    'request_method' => 'curl',

    /*
    |--------------------------------------------------------------------------
    | Enable/Disable Service
    |--------------------------------------------------------------------------
    | Type: bool
    |
    | This option is used to disable/enable the service
    |
    | Supported: true, false
    |
    */
    'is_service_enabled' => true,

    /*
    |--------------------------------------------------------------------------
    | Host Name
    |--------------------------------------------------------------------------
    | Type: string
    | Default will be empty, assign value only if you want domain check with Google response
    | Google reCAPTCHA host name, https://www.google.com/recaptcha/admin
    |
    */
    'host_name' => '',

    /*
    |--------------------------------------------------------------------------
    | Secret Key
    |--------------------------------------------------------------------------
    | Type: string
    | Google reCAPTCHA credentials, https://www.google.com/recaptcha/admin
    |
    */
    'secret_key' => env('RECAPTCHA_V3_SECRET_KEY', ''),

    /*
    |--------------------------------------------------------------------------
    | Site Key
    |--------------------------------------------------------------------------
    | Type: string
    | Google reCAPTCHA credentials, https://www.google.com/recaptcha/admin
    |
    */
    'site_key' => env('RECAPTCHA_V3_SITE_KEY', ''),

    /*
    |--------------------------------------------------------------------------
    | Badge Style
    |--------------------------------------------------------------------------
    | Type: boolean
    | Support:
    |  -  true: the badge will be shown inline within the form, also you can customise your style
    |  -  false: the badge will be shown in the bottom right side
    |
    */
    'inline' => false,

    /*
    |--------------------------------------------------------------------------
    | Background Badge Style
    |--------------------------------------------------------------------------
    | Type: boolean
    | Support:
    |  -  true: the background badge will be displayed at the bottom right of page
    |  -  false: the background badge will be invisible
    |
    */
    'background_badge_display' => true,

    /*
    |--------------------------------------------------------------------------
    | Background Mode
    |--------------------------------------------------------------------------
    | Type: boolean
    | Support:
    |  -  true: the script will run on every page if you put init() on the global page
    |  -  false: the script will only be running if there is action defined
    |
    */
    'background_mode' => true,

    /*
    |--------------------------------------------------------------------------
    | Score Comparision
    |--------------------------------------------------------------------------
    | Type: bool
    | If you enable it, the package will do score comparision from your setting
    */
    'is_score_enabled' => true,

    /*
    |--------------------------------------------------------------------------
    | Setting
    |--------------------------------------------------------------------------
    | Type: array
    | Define your score threshold, define your action
    | action: Google reCAPTCHA required parameter
    | threshold: score threshold
    | score_comparision: true/false, if this is true, the system will do score comparision against your threshold for the action
    */
    'setting' => [
        [
            'action' => 'contactform',
            'threshold' => 0.5,
            'score_comparision' => true,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Setting
    |--------------------------------------------------------------------------
    | Type: array
    | Define a list of ip that you want to skip
    */
    'skip_ips' => [

    ],

    /*
    |--------------------------------------------------------------------------
    | Options
    |--------------------------------------------------------------------------
    | Custom option field for your request setting, which will be used for RequestClientInterface
    |
    */
    'options' => [

    ],

    /*
    |--------------------------------------------------------------------------
    | API JS Url
    |--------------------------------------------------------------------------
    | Type: string
    | Google reCAPTCHA API JS URL
    | use:
    */
    'api_js_url' => 'https://www.google.com/recaptcha/api.js',

    /*
    |--------------------------------------------------------------------------
    | Site Verify Url
    |--------------------------------------------------------------------------
    | Type: string
    | Google reCAPTCHA API
    | please use "www.recaptcha.net" in your code in circumstances when "www.google.com" is not accessible. e.g China
    | e.g. https://www.recaptcha.net/recaptcha/api.js
    */
    'site_verify_url' => 'https://www.google.com/recaptcha/api/siteverify',

    /*
    |--------------------------------------------------------------------------
    | Language
    |--------------------------------------------------------------------------
    | Type: string
    | https://developers.google.com/recaptcha/docs/language
    */
    'language' => 'en',
];

However, I am getting a weird rendering issue where it is rendering in the middle of the page.
Screenshot from 2020-06-08 13-38-15

But, if I do not render any recaptcha fields on the page, then it is rendered in the bottom right of the page. I'm pretty confident this has to do with explicit rendering being enabled when there is an action defined. https://github.com/RyanDaDeng/laravel-google-recaptcha-v3/blob/master/resources/views/googlerecaptchav3/template.blade.php#L25
With explicit rendering, it is rendering the badge in the first reCAPTCHA div on the page instead of within the body tag.

I feel like explicit rendering should only be defined if the config 'inline' => true, is set. At least, that's what I would think based on the comments from the config file as a new user of this package.

Error with vue component: gRecaptchaResponse: ["invalid-input-secret"]

Hi there,

I'm trying to use the vue component in my register from.

I have added my keys to .env file
RECAPTCHA_V3_SECRET_KEY=XXX RECAPTCHA_V3_SITE_KEY=XX

I have published the vue component as described in the installation docu.

I have added the rule to my RegisterUserRequest.php
`
use TimeHunter\LaravelGoogleReCaptchaV3\Validations\GoogleReCaptchaV3ValidationRule;
...

public function rules()
{
return [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:8|confirmed',
'gRecaptchaResponse' => ['required', new GoogleReCaptchaV3ValidationRule('sign_up')]
];
}
`

I have imported and added the component to my form.
<google-re-captcha-v3 v-model="registerForm.gRecaptchaResponse" ref="captcha" site-key="XXX" id="sign_up_id" inline action="sign_up" ></google-re-captcha-v3> ....

And I have double checked if the sitekey and secret keys are correct.

The badge gets displayed correctly. the v-model gRecaptchaResponse has a pretty long string inside. But when I submit the form I get an error response with the message gRecaptchaResponse: ["invalid-input-secret"].

What could be the cause of that problem?

No way to translate message timeout-or-duplicate

If I let 2 minutes pass before I submit the form, the response comes with this message:
timeout-or-duplicate

I suppose it is normal but I don't find how to translate it, Am I missing something?

My temporary solution was to modify the GoogleReCaptchaV3ValidationRule / passes(), like this:

public function passes($attribute, $value)
    {
        $response = GoogleReCaptchaV3::setAction($this->action)->verifyResponse($value, app('request')->getClientIp());
        $this->message = $response->getMessage();
        if($this->message == 'timeout-or-duplicate')$this->message = trans('GoogleReCaptchaV3::messages.TIMEOUT_OR_DUPLICATE');
        return $response->isSuccess();
    }

Is this a bug? or some google update? What do you suggest?

README Error - Wrong ValidationClass name

Good morning!

Following the README process to use the Validation Class, I arrived on a NotFound Exception.

REAME content:

use TimeHunter\LaravelGoogleReCaptchaV3\Validations\GoogleReCaptchaValidationRule;
$rule = [
    'g-recaptcha-response' => [new GoogleReCaptchaValidationRule('action_name')]
];

According to your code:

The class actually has V3 in its name.

use TimeHunter\LaravelGoogleReCaptchaV3\Validations\GoogleReCaptchaV3ValidationRule;
$rule = [
    'g-recaptcha-response' => [new GoogleReCaptchaV3ValidationRule('action_name')]
];

This resolves the issue.

Thanks for this package.

Unable to use properly with Vue

After submitting the form in vue, the page is returned as domain.com/?g-recaptcha-response=XXXXXXXXXX and doesn't continue the process.
I'm implementing the recaptcha in vue login request and the code in my component is the following.
It doesn't return none of error.
Can someone help me please?

config/googlerecaptchav3.php

'setting' => [
        [
            'action' => 'action',
            'threshold' => 0.2,
            'score_comparision' => false,
        ],

Template

 <google-re-captcha-v3
            v-model="gRecaptchaResponse"
            ref="captcha"
            :site-key="mySiteKeyVariable"
            action="action"
            id="action_id"
        ></google-re-captcha-v3>

method

axios.post('/login',{recaptcha:this.gRecaptchaResponse,_token:csrf,email:this.email,password:this.password,remember:this.remember}).then((res)=>{                this.loading=false;
                        this.toast(res.data.location,1);
                       this.$refs.captcha.execute();
                   }).catch((error)=>{
                        this.Error=error.response.data.message;
                        this.loading=false;
                        this.toast();
                        this.$refs.captcha.execute();
                    });

Controller

$rules = [
            'recaptcha' => [new GoogleReCaptchaV3ValidationRule('frontier_action')],
            'email'=>'required|email',
            'password'=>'required',
        ];
        info($request->all());
        $validator = \Illuminate\Support\Facades\Validator::make($request->only('email','password','recaptcha'),$rules);
        if($validator->fails()){
            return response()->json(['errors'=>$validator->errors()],400);
        }
$route=route('home');
         return response()->json(['message' => 'Successfully Login', 'location' => $route], 200);

Having trouble using the package on a site using vue.js.

Hi there,

Thanks for the package.

I managed to install it nicely on a new Laravel install but on the project I was planning on using it, which uses vue.js it's is giving me issues.

I tried adding {!! GoogleReCaptchaV3::render(['signup_id'=>'signup']) !!} to the footer of my below the main app.js file in the footer of my site and in the tag.

The component seems to work nicely but I'm running into "Error: reCAPTCHA placeholder element must be an element or id" on every page that doesn't have the

tag.

I'm assuming I need to use the vue file but I don't know how to implement it.

Could you provide some documentation on how to use the vue file?

Thanks!

Including on every pages throws ErrorException: Undefined variable: apiJsUrl

To reproduce simply put {!! GoogleReCaptchaV3::init() !!} in the footer of your page layout with the default configuration (background mode on) and the site will crash.

This is happening because https://github.com/RyanDaDeng/laravel-google-recaptcha-v3/blob/master/src/GoogleReCaptchaV3.php#L67 which prepares the variables for the view does not contain apiJsUrl as a view variable which is required for the plugin to initialise.

Struggling to implement on registration

I'm guessing this is user error as I'm relatively new to Laravel. I am trying to use Recaptcha v3 on the standard registration form that comes with Laravel.

In the config file I have:
'setting' => [
[
'action' => 'login',
'threshold' => 0.5,
'inline' => true,
'score_comparision' => false,
],
[
'action' => 'registration',
'threshold' => 0.5,
'inline' => true,
'score_comparison' => false,
],
],

In the blade I have all the normal fields plus:


@csrf
...


{{ __('Register') }}

...
{!! GoogleReCaptchaV3::render([
'registration_id'=>'registration'
]) !!}

In the controller I have:
protected function validator(array $data)
{
return Validator::make($data, [
'g-recaptcha-response' => [new GoogleReCaptchaV3ValidationRule('registration')],
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}

What am I missing?
Thanks!

Token is null

I added the following as a vue file in the Vue cli project.

<template>
  <div :id="id" />
</template>

<script>
export default {
  name: 'GoogleRecaptcha',
  props: {
    action: {
      type: String,
      required: false,
      default: 'validate_grecaptcha'
    },
    id: {
      type: String,
      required: false,
      default: 'grecaptcha_container'
    },
    siteKey: {
      type: String,
      required: false, // set to true if you don't want to store the siteKey in this component
      default: '' // set siteKey here if you want to store it in this component
    },
    inline: {
      type: Boolean,
      required: false,
      default: false,
    },
  },
  data() {
    return {
      captchaId: null,
    }
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      if (!document.getElementById('gRecaptchaScript')) {
        window.gRecaptchaOnLoadCallbacks = [this.render];
        window.gRecaptchaOnLoad = function () {
          for (let i = 0; i < window.gRecaptchaOnLoadCallbacks.length; i++) {
            window.gRecaptchaOnLoadCallbacks[i]();
          }
          delete window.gRecaptchaOnLoadCallbacks;
          delete window.gRecaptchaOnLoad;
        };
        let recaptchaScript = document.createElement('script');
        recaptchaScript.setAttribute('src', 'https://www.google.com/recaptcha/api.js?render=explicit&onload=gRecaptchaOnLoad');
        recaptchaScript.setAttribute('id', 'gRecaptchaScript');
        recaptchaScript.async = true;
        recaptchaScript.defer = true;
        document.head.appendChild(recaptchaScript);
      } else if (!window.grecaptcha || !window.grecaptcha.render) {
        window.gRecaptchaOnLoadCallbacks.push(this.render);
      } else {
        this.render();
      }
    },
    render() {
      this.captchaId = window.grecaptcha.render(this.id, {
        sitekey: this.siteKey,
        badge: this.inline === true ? 'inline' : '',
        size: 'invisible',
        'expired-callback': this.execute
      });
      this.execute();
    },
    execute() {
      window.grecaptcha.execute(this.captchaId, {
        action: this.action,
      }).then((token) => {
        this.$emit('input', token);
      });
    }
  }
}
</script>

Then I imported the vue file. I used the vue component, whose name is google-recaptcha, as follows.

<div>
            <google-recaptcha
              id="contact_us_id"
              ref="captcha"
              v-model="form.recaptcha"
              :site-key="siteKey"
              inline
              action="contact_us"
            />
          </div>

siteKey is 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI

While the page is loading, the following requests are dropped.
Screen Shot 2021-04-27 at 22 28 45

But while these requests are being sent, the input event does not receive your token.
Screen Shot 2021-04-27 at 22 30 11

After waiting for a while, it sends the reload request again and takes the token here. How can I get the token when first making these requests.

not reading published config file

Hi,

for some reason, the copied config file is not being read. I spent a long time trying to find what I was doing wrong, without any success. I was getting an error message on the console saying: missing site key. So I put the site key string directly on the config file inside the vendor folder, since then I didn't get the error message anymore. Am I doing something wrong or there is indeed a bug?

Thanks.

Curl Error Code: GoogleReCaptchaV3::messages.ERROR_TIMEOUT

Configured my app as described. Tried using with rendorOne, rendor and even rendorField, all of them giving the same error -

Curl Error Code: GoogleReCaptchaV3::messages.ERROR_TIMEOUT

Have {!! GoogleReCaptchaV3::init() !!} at the bottom of my page.

Using Laravel 5.7.28

Please guide me through this.

Thanks in advance.

Service provider doesn't support 5.4 version

My Laravel version 5.4
When I add providers and aliases at config/app.php
I have error below this

In GoogleReCaptchaV3ServiceProvider.php line 44:

  Call to undefined method Illuminate\Foundation\Application::has()

token times out after x time.

I have a large form to fill in on my website.
After some time, the token times out.
Is this by design or am i missing something?
If by design, what is the best way to refresh the token before timing out?

How to use refresh without vue.js?

I have simple modal dialog controlled with jquery. If Laravel validation return error, next submit does not work because ReCaptcha token is not refreshed. How can I run refresh token in this case?

Question

Hello, I'm a newcomer, sorry to bother you with these stupid questions.

  • do we add is_score_enabled again inside setting => [] ? cause that what I see in readme but I think we already have, outside.

  • I have DesignRequest extends FormRequest

and in rules() method I add

'g-recaptcha-response' => ['required', new GoogleReCaptchaV3ValidationRule('submit_design')]

in controller I injected it.
in view:

<form action=design.store>
// other fields...
{!! GoogleReCaptchaV3::renderField('submit_design_id','submit_design') !!}
</form>

I have the badge appeared
because {!! GoogleReCaptchaV3::init() !!}
and everything seems fine when I submitted a request.

but I want to know if I've configured it right so I assign wrong value for my secret key but I got no error.
Any idea?

TIMEOUT_OR_DUPLICATE

I'm using your component in Vue.js however I notice that when the user fills out a very large form, spending too much time on screen, the first request will give the timeout message and the user will need to click again to submit the form.

Is there any alternative to increase this time, or when it exceeds the time, automatically make a new request to get a new token?

Getting timeout error

I'm using recpatcha in Vue. I call this method: this.$refs.captcha.execute(); after the user login success or erro and after logout. Anytime I call it returns this two errors:

recaptcha__pt_br.js:500 Timeout (n)
Uncaught (in promise) Timeout (n)

Even so the token works in the authentication every time the user log in. In the first place or after logout without refresh the page.

Error message of Response could has multi-lang ?

Hi,
First, It’s awesome. This package is really help to me πŸ‘

I notice the Core/GoogleReCaptchaV3Response has declare const var like this (maybe not only in here πŸ˜„ ) :
const MISSING_INPUT_ERROR = 'Missing input response.';
const ERROR_UNABLE_TO_VERIFY = 'Unable to verify.';
const ERROR_HOSTNAME = 'Hostname does not match.';
const ERROR_ACTION = 'Action does not match.';
const ERROR_SCORE_THRESHOLD = 'Score does not meet threshold.';
const ERROR_TIMEOUT = 'Timeout';

if have any chance, could you please support multi-lang message setting for those message ?
Thanks ^^

Issue of generating renderField with @include

Hello,

I was using this package with shortcodes. Today I attempted to use {!! GoogleReCaptchaV3::renderField('contactCaptcha','contactSubmit','','z-index: 999;') !!} with @include a blade file however, same blade file works fine with returning a view but when I include it in HTML, it's not rendering recaptcha, instead it only creates empty div.

By the way, my first git post ever! :)

Cenk

[Idea] Auto check on FormRequest resolve

just like how laravel will automatically validate a for rules on a FormRequest when it is resolved, it should be possible to do the same thing with Recaptcha with a interface and trait

class MyRequest extends FormRequest implements RequiresRecaptcha {
    use HandlesRecaptcha

    protected $min_recaptcha_score = 0.3;
}

and then in the service provider

$this->app->afterResolving(RequiresRecaptcha::class, function ($resolved) {
    $resolved->handlesRecaptcha();
});

add multiple recaptcha

I have two popups on same page and both have their own recaptcha but there is an error on console. it says "reCAPTCHA has already been rendered in this element".
Can I use multiple recaptcha in single page?
Laravel : 5.5.46
Vue : 2.6.10

An error occurs when using renderField()

Thanks for the development.

When I use "renderField()" like this:

<form method="POST" action="/verify">
   {!!  GoogleReCaptchaV3::renderField('contact_us_id','contact_us_action') !!}
    <input type="submit" value="submit">
</form>

This error occurs.
Type error: Too few arguments to function

What this '$class' means?
GoogleReCaptchaV3::renderField($id,$action,$class,$style)
If my configuration is correct, will this '$class' be injected?

regards.

Blade does not support background script and missing ID check if the id not exist

Issue:
The script always require variables to render the reCAPTCHA, I want to have it run in background. And the template file missing ID check.

Error:
if '{{$field}}' (id) is don't contain in current page , js will stop at error code

try{
let client{{$field}} = grecaptcha.render('{{$field}}', {
'sitekey': '{{$publicKey}}',
@if($inline===true) 'badge': 'inline', @endif
'size': 'invisible',
'hl': '{{$language}}'
});
grecaptcha.ready(function () {
grecaptcha.execute(client{{$field}}, {
action: '{{$action}}'
});
});
}catch(err) {}

rendering issues

Hello,

First of all thank you for the package.

Maybe I did wrong but the init() method does not render correctly :
β€’ it does not render the reCaptcha V3 Api.js
β€’ all the action name is merged with the string '-contact'

My laravel version is 6.2 and this is what I do by following your documentation.

My Blade File, before the /body :
{!! GoogleReCaptchaV3::init() !!}

in the $.ajax() :
my data to send data:$.extend($(this), {'g-recaptcha-response': getReCaptchaV3Response('id_div_inline_recaptcha_badge')}).serialize()

in my success/error calback :
refreshReCaptchaV3('id_div_inline_recaptcha_badge', 'visitor-contact');

my form :
@csrf {{-- inputs... --}} {!! GoogleReCaptchaV3::renderField('id_div_inline_recaptcha_badge', 'visitor-contact') !!}

I check the log and and network console, no errors raised, but there is no google api.js and all my action have the '-contact' appended (so in this case, my action becomes 'visitor-contact-contact')

Thank you for reading

Deactivate CURLOPT_SSL_VERIFYPEER via config

Could you add a config option to deactivate CURLOPT_SSL_VERIFYPEER via config for testing purpose ?

likewise :
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, config('captcha.verify', true));

Thanks and great job

Edit: there is a "options" field in the googlecaptchav3.php config file but the CurlRequestClient.php don't use its $options params

Issue timeout-or-duplicate

I often (but not always..) get timeout-or-duplicate on first submit try, and on second submit the POST pass.
It seems it can happen when the validation process is run twice..? Any idea ?

(Also, even if it fails, isn't it suppose to fallback on V2 ? I thought it was suppose to, but i don't see it anymore in README, maybe I mix up with some other project ?)

Error: The action is timeout.

Hello, I have a problem with this error.

I checked every issue here and all of them are timeouts after 2 minutes of page loading, but for me, the problem occurs after page load < 2 minutes. More precisely seconds after js load and submit.

Laravel 8, PHP 7.3.7
My controller:

class ReservationController extends Controller
{
    public function createReservation(Request $request){

         // Here validation fails with timeout message
        $request->validate([
            'room' => 'required|exists:rooms,id',
            'email' => 'required|email',
            'phone' => 'required|max:128',
            'dateReservation' => ['required', new DateInPastCheck, new DateArrivalLeaveCheck],
            'name' => 'required|string|min:3|max:150',
            'g-recaptcha-response' => [new GoogleReCaptchaV3ValidationRule('order')],
        ]);

       // ...
    }
}

But when I test before request validation everything passes normally.

class ReservationController extends Controller
{
    public function createReservation(Request $request){

        dd(GoogleReCaptchaV3::verifyResponse(
            $request->input('g-recaptcha-response'),
            $request->getClientIp()
            )
         ->getMessage());

        // ....
    }
}

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.