2017-02-10 30 views
8

Próbuję zaimplementować Invisible reCAPTCHA za pomocą React i formularza Redux. Ogólnie rzecz biorąc, przepływ pracy Invisible reCAPTCHA to:Implementacja Invisible reCAPTCHA z formą Redux

  1. Oddaj "niewidzialną" CAPTCHA, zwracając identyfikator widgetu.
  2. Zadzwoń pod grecaptcha.execute z identyfikatorem widżetu. W razie potrzeby użytkownik zostanie poproszony o rozwiązanie problemu. Wynik jest przekazywany do funkcji zwrotnej określonej podczas renderowania CAPTCHA.
  3. Wyślij formularz razem z wynikiem CAPTCHA.

Utworzyłem reagować składnik przeznaczony do stosowania z Redux formularza Field że renderuje CAPTCHA i aktualizuje stan forma po grecaptcha.execute nazywa się:

class ReCaptcha extends React.Component { 
    render() { 
    return <div ref={div => this.container=div} /> 
    } 

    componentDidMount() { 
    const { input: { onChange }, sitekey } = this.props 
    grecaptcha.render(this.container, { 
     sitekey, 
     size: "invisible", 
     callback: onChange 
    }) 
    } 
} 

Jednak nie wiem jak lub gdzie zadzwonić pod numer grecaptcha.execute wraz z identyfikatorem widżetu po złożeniu formularza przez użytkownika. Nie mogę tego nazwać w onSubmit, ponieważ identyfikator widżetu nie jest tam dostępny. Mogę nazwać to w ReCaptcha natychmiast po renderowaniu CAPTCHA, ale jeśli użytkownik potrzebuje rozwiązać CAPTCHA, zostanie poproszony o zrobienie tego, gdy tylko formularz zostanie wyrenderowany.

Ten numer minimal working example pokazuje, co osiągnąłem do tej pory.

Odpowiedz

0

Użyj podpórki onSubmit, aby wywołać funkcję grecaptcha.execute(), i wskaż wywołanie danych do "rzeczywistej" funkcji onSubmit.

let refToMyWidget; 
const { handleSubmit } = this.props; 

componentDidMount() { 
    if (window.grecaptcha) { 
    refToMyWidget = window.grecaptcha.render(this.container, { 
     sitekey: "xxxx", 
     size: "invisible", 
     callback: handleSubmit(this.actuallySubmit) 
    }) 
    } 
} 

preSubmit() { 
    if(!window.grecaptcha) { 
    return; 
    } 
    window.grecaptcha.execute(this.refToMyWidget) 
} 

actuallySubmit() { 
    // submission logic here 
} 

render() { 
    return (
    <form onSubmit={handleSubmit(this.preSubmit)}> 
     <Field name="foo" component="input" /> 
     <button>Submit</button> 
    </form> 
) 
} 

N.b. Nie testowałem tego kodu, ale powinno być mniej więcej w porządku. Jeśli napotkasz problemy z ładowaniem grecaptcha do strony/formularza, znalazłem bardzo pomocny kod this.

0

Musiałem zrobić dla mnie niewidzialną pracę z RECAPTCHA, ponieważ widoczna nie reaguje. Here to przykład, który zaimplementowałem.

Pierwszą rzeczą do zrobienia jest dodanie poniżej tagu do ciała (lub można użyć react-helmet).

<script src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" async defer></script> 

Uproszczona wersja mojego kodu pracy:

import React from 'react'; 

class YourComponent extends React.Component { 
    componentDidMount() { 
    // Create a script to make sure the reCAPTCHA API is called. 
    const script = document.createElement('script'); 
    script.text = ` 
     var onloadCallback = function() { 
     console.log('grecaptcha is ready'); 
     }; 
    `; 
    document.body.appendChild(script); 

    // We will render reCAPTCHA after the page is loaded, 
    // because we want to bind our own submit methods. 
    window.addEventListener('load', this.onLoad); 
    } 

    // Runs once the form is submitted. 
    onRecaptcha = (e) => { 
    e.preventDefault(); 
    const { grecaptcha } = window; 
    grecaptcha.execute(); 
    }; 

    // Real submit function. 
    onSubmit = (token) => { 
    // I'm not sure what token could be if recaptcha fails. 
    // In my case it seems successful and returns a long string. 
    console.log(token); 

    // Your real action goes below... 
    }; 

    onLoad =() => { 
    // Now we define our reCAPTCHA 
    if (window.grecaptcha) { 
     const { grecaptcha } = window; 
     grecaptcha.render('recaptcha', { // div#recaptcha 
     sitekey : '', 
     size  : 'invisible', 
     callback : this.onSubmit 
     }); 
    } 
    }; 

    render() { 
    return (
     <div> 
     <Helmet> 
      <script 
      src="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit" 
      async 
      defer 
      /> 
     </Helmet> 
     <form onSubmit={this.onRecaptcha}> 
      <div id="recaptcha" /> 
      <button type="submit">Submit</button> 
     </form> 
     </div> 
    ); 
    } 
} 

export default YourComponent; 
+0

Mam zorientowali się, że o wiele łatwiej z [scriptjs] (https://github.com/ded/script.js) biblioteki. Przekażę przykład, jeśli chcesz. –