laravel-google-recaptcha-v3 icon indicating copy to clipboard operation
laravel-google-recaptcha-v3 copied to clipboard

Token is null

Open kerimkuscu opened this issue 3 years ago • 3 comments

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.

kerimkuscu avatar Apr 27 '21 19:04 kerimkuscu

checking tonight

RyanDaDeng avatar May 03 '21 03:05 RyanDaDeng

same error, token is null I work on vue3 but i m not using api composition

Luigidefra avatar May 28 '21 15:05 Luigidefra

I had the same error. Try to change execute() method in GoogleReCaptchaV3.vue component (line 80) to:

execute() {
    window.grecaptcha.execute(this.captchaId, {
        action: this.action,
    }).then((token) => {
        this.$emit('update:modelValue', token); // this line
    });
}

See docs...

AGNICO avatar Nov 21 '21 23:11 AGNICO