
рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ рдореИрдВ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдХрд┐ рдЧреВрдЧрд▓ рд╕реЗ рдХреИрдкреНрдЪрд╛ рдХреИрд╕реЗ рдХрдиреЗрдХреНрдЯ рдХрд░реЗрдВ (reCAPTCHA) Vue JS рд╕реЗ рдФрд░ рд╕рд░реНрд╡рд░ рдкрд░ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛ рдорд╛рдиреНрдп рдХрд░реЗрдВ (рдореИрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ рд▓рд╛рд░рд╡реЗрд▓ / рд▓реБрдореЗрди рдкрд░ рдмреИрдХрдПрдВрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реВрдВ, рд▓реЗрдХрд┐рди рд╕рддреНрдпрд╛рдкрди рдХрд╛ рд╕рд┐рджреНрдзрд╛рдВрдд рд╕рднреА рдкреНрд░реМрджреНрдпреЛрдЧрд┐рдХрд┐рдпреЛрдВ рдХреЗ рд▓рд┐рдП рд╕рдорд╛рди рд╣реИ)ред
рдкреНрд░рд╕реНрддрд╛рд╡рдирд╛
рд╣рдо рдЕрджреГрд╢реНрдп reCAPTCHA рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рдпрд╣ рдПрдХ рдЕрджреГрд╢реНрдп * рдХреИрдкреНрдЪрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рддрдм рддрдХ рдкрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реИ рдЬрдм рддрдХ рдХрд┐ рд╕рд┐рд╕реНрдЯрдо рдЗрд╕реЗ рдЖрд╡рд╢реНрдпрдХ рдирд╣реАрдВ рдорд╛рдирддрд╛ ред рд╕рд╛рдЗрдЯ рд╡реНрдпрд╡рд╕реНрдерд╛рдкрдХ рдПрдХ рдереНрд░реЗрд╢реЛрд▓реНрдб рд╕реНрддрд░ (рд╕реБрд░рдХреНрд╖рд╛ рд╡рд░реАрдпрддрд╛) рд╕реЗрдЯ рдХрд░ рд╕рдХрддрд╛ рд╣реИ, рдЬрд┐рд╕ рдкрд░ рд╕рд┐рд╕реНрдЯрдо рдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреЛ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕рддреНрдпрд╛рдкрди рд╕реЗ рдЧреБрдЬрд░рдирд╛ рд╣реЛрдЧрд╛ред
* - reCAPTCHA рдЖрдЗрдХрди рдЕрднреА рднреА рдкреГрд╖реНрда рдкрд░ рдореМрдЬреВрдж рд╣реЛрдирд╛ рдЪрд╛рд╣рд┐рдПред

рд╕рд╛рдЗрдЯ рдкрд░ рдЕрджреГрд╢реНрдп рдХреИрдкреНрдЪрд╛ред
рдкреНрд░рд╢реНрди / рдЙрддреНрддрд░
рдХрд╛рдо рд╢реБрд░реВ рдХрд░рдиреЗ рд╕реЗ рдкрд╣рд▓реЗ, рдореИрдВ рдЙрди рд╕рд╡рд╛рд▓реЛрдВ рдХрд╛ рдЬрд╡рд╛рдм рджреЗрдирд╛ рдЪрд╛рд╣реВрдВрдЧрд╛, рдЬрдм рдореИрдВрдиреЗ Google reCAPTCHA рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдерд╛ред
рдкреНрд░рд╢реНрди: reCAPTCHA рдХреА рд▓рд╛рдЧрдд рдХрд┐рддрдиреА рд╣реИ?
A: Google рд╕реЗ ReCAPTCHA рдПрдХ рдирд┐рдГрд╢реБрд▓реНрдХ рдЯреВрд▓ рд╣реИред
рдкреНрд░рд╢реНрди: рдпрджрд┐ рд╕рд╛рдЗрдЯ рдкрд░ рдкрд╣рд▓реЗ рд╣реА рдХреИрдкреНрдЪрд╛ рдкрд╛рд╕ рд╣реЛ рдЧрдпрд╛ рд╣реИ, рддреЛ рдореБрдЭреЗ рдмреИрдХрдПрдВрдб рдкрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреНрдпреЛрдВ рд╣реИ?
A: рдЬрдм рдЖрдк рд╕рд░реНрд╡рд░ рд╕реЗ рдЕрдиреБрд░реЛрдз рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рд╕реЗ рднреЗрдЬрддреЗ рд╣реИрдВ:
POST /register 1.1 HTTP Host: www.example.com { "email:"user@gmail.com", "password": "supersecret", "recaptcha-token":"01ASJASJFZ_AASD3115..." }
рдпрджрд┐ рдЖрдк рдмреИрдХреЗрдВрдб рдкрд░ рдХреИрдкреНрдЪрд╛ рдЯреЛрдХрди рдХреА рдЬрд╛рдВрдЪ рдирд╣реАрдВ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдмреЙрдЯ рдЗрд╕ рдЯреЛрдХрди рдХреЗ рдмрд┐рдирд╛ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд╕рд╛рде рд╕реНрдкреИрдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдЗрд╕реЗ рдбрдореА рдХреЗ рд╕рд╛рде рдмрджрд▓ рд╕рдХрддреЗ рд╣реИрдВред
рдкреНрд░рд╢реНрди: рдореЗрд░реА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рд╣реИ, рдореБрдЭреЗ рдХреНрдпрд╛ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП?
A: рд░рд┐рдПрдХреНрдЯ JS рдПрдХ рдмрд╣реБрдд рдЕрдЪреНрдЫреА рдмрд╛рдд рд╣реИред рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рд╡реЗрдмрд╕рд╛рдЗрдЯ рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рддреЛ рдореИрдВ рдЖрдкрдХреЛ https://github.com/appleboy/react-recaptcha рдкрд░ рдзреНрдпрд╛рди рджреЗрдиреЗ рдХреА рд╕рд▓рд╛рд╣ рджреЗрддрд╛ рд╣реВрдВред рдСрдкрд░реЗрд╢рди рдХрд╛ рд╕рд┐рджреНрдзрд╛рдВрдд Vue рдХреЗ рд╕рд╛рде рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рдорд╛рди рд╣реИред
рдХрд╛рдо рдкрд░ рд▓рдЧрдирд╛
рдЗрд╕рд▓рд┐рдП, рдЗрд╕рд╕реЗ рдкрд╣рд▓реЗ рдХрд┐ рд╣рдо рдЦрд╛рдирд╛ рдмрдирд╛рдирд╛ рд╢реБрд░реВ рдХрд░реЗрдВ, рд╣рдореЗрдВ рд╕рд╛рдордЧреНрд░реА рдХреА рдПрдХ рд╕реВрдЪреА рдЪрд╛рд╣рд┐рдП:
рдЪрд░рдг # 1: рдЕрдкрдиреА рд╕рд╛рдЗрдЯ рдкрд░ reCAPTCHA рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреБрдВрдЬрд┐рдпрд╛рдБ рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВ
рд╣рдореЗрдВ Google рд╡реЗрдмрд╕рд╛рдЗрдЯ рдкрд░ рд╕рд╛рдЗрдЯ рдХреБрдВрдЬреА рдФрд░ рдЧреБрдкреНрдд рдХреБрдВрдЬреА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ: https://www.google.com/recaptcha/admin#list

рдЖрдк рд▓реЗрдмрд▓ рдлрд╝реАрд▓реНрдб рдореЗрдВ рдХреБрдЫ рднреА рд▓рд┐рдЦ рд╕рдХрддреЗ рд╣реИрдВред
рдЕрдЧрд▓рд╛, рдкреНрд░рдХрд╛рд░ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ - рдЕрджреГрд╢реНрдп reCAPTCHA рдмрд┐рд▓реНрд▓рд╛ ред
рдЖрдк рдХрдИ рдбреЛрдореЗрди рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЬрд┐рд╕ рдкрд░ рдЖрдк рдХреИрдкреНрдЪрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВрдЧреЗред
рдПрдХ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд░реВрдк рдореЗрдВ, рдореИрдВрдиреЗ yourawesomedomain.com рдФрд░ localhost рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд┐рдпрд╛ рд╣реИред
рд╣рдо рдЙрдкрдпреЛрдЧ рдХреА рд╢рд░реНрддреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реИрдВред

рдЖрдкрдХреЛ рджреЛ рдЪрд╛рдмрд┐рдпрд╛рдВ рджреА рдЧрдИ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ рд╕реБрд░рдХреНрд╖рд┐рдд рд╕реНрдерд╛рди рдкрд░ рд░рдЦреЗрдВред рд╣рдо рдмрд╛рдж рдореЗрдВ рдЙрдирдХреЗ рдкрд╛рд╕ рд▓реМрдЯ рдЖрдПрдВрдЧреЗред
рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдЗрд╕ рдХреЛрдб рдХреЛ рд╣реЗрдб рд╕реЗрдХреНрд╢рди рдореЗрдВ рдЬреЛрдбрд╝рдирд╛ рд╣реЛрдЧрд╛:
<script src="https://www.google.com/recaptcha/api.js?onload=vueRecaptchaApiLoaded&render=explicit" async defer></script>
рдУрдирд▓реЛрдб рд╕рдВрдкрддреНрддрд┐ рд╣рдорд╛рд░реЗ рдШрдЯрдХ рдХреЛ рдмрддрд╛рдПрдЧреА рдХрд┐ рдХреИрдкреНрдЪрд╛ рдЙрдкрдпреЛрдЧ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИред
рдЕрдЧрд▓рд╛ рдореИрдВ рддреИрдпрд╛рд░ рдШрдЯрдХ рджрд┐рдЦрд╛рдКрдВрдЧрд╛ рдФрд░ рд╣рдо рдЗрд╕реЗ рднрд╛рдЧреЛрдВ рдореЗрдВ рд╡рд┐рд╢реНрд▓реЗрд╖рдг рдХрд░реЗрдВрдЧреЗ:
<template> <div id="app"> <div class="container my-4"> <div class="row justify-content-center"> <div class="col-md-8"> <h2 class="text-center mb-4"> Sign Up Form with Google reCAPTCHA </h2> <form method="post" @submit.prevent="validate"> <div class="form-group"> <input type="email" name="email" class="form-control" placeholder="Enter your e-mail address" required /> </div> <div class="form-group"> <input type="password" name="password" class="form-control" placeholder="Enter your password" required /> </div> <div class="form-group"> <vue-recaptcha ref="recaptcha" size="invisible" :sitekey="sitekey" @verify="register" @expired="onCaptchaExpired" /> <button type="submit" class="btn btn-primary btn-block"> Sign Up </button> </div> </form> </div> </div> </div> </div> </template> <script> import VueRecaptcha from 'vue-recaptcha' export default { name: 'Register', components: { VueRecaptcha }, data () { return { email: null, password: null, sitekey: ' SITE KEY' } }, methods: { register (recaptchaToken) { axios.post('https://yourserverurl.com/register', { email: this.email, password: this.password, recaptchaToken: recaptchaToken }) }, validate () { </script>
рдШрдЯрдХ рдЙрджрд╛рд╣рд░рдг VideVateate рдХрд╛ рдЙрдкрдпреЛрдЧ рдлрд╝реАрд▓реНрдбреНрд╕ рдХреЛ рдорд╛рдиреНрдп рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП <template> <div id="app"> <div class="container my-4"> <div class="row justify-content-center"> <div class="col-md-8"> <h2 class="text-center mb-4"> Sign Up Form with Google reCAPTCHA </h2> <form method="post" @submit.prevent="validate"> <div class="form-group"> <input type="email" name="email" class="form-control" placeholder="Enter your e-mail address" v-validate.disable="'required|email'" required /> <div v-show="errors.has('email')" class="invalid-feedback d-block" > {{ errors.first('email') }} </div> </div> <div class="form-group"> <input type="password" name="password" class="form-control" placeholder="Enter your password" v-validate.disable="'required|min:6|max:32'" required /> <div v-show="errors.has('password')" class="invalid-feedback d-block" > {{ errors.first('password') }} </div> </div> <div class="form-group"> <vue-recaptcha ref="recaptcha" size="invisible" :sitekey="sitekey" @verify="register" @expired="onCaptchaExpired" /> <button type="submit" class="btn btn-primary btn-block"> Sign Up </button> </div> </form> </div> </div> </div> </div> </template> <script> import VueRecaptcha from 'vue-recaptcha' export default { name: 'Register', components: { VueRecaptcha }, data () { return { email: null, password: null, sitekey: ' SITE KEY' } }, methods: { register (recaptchaToken) { axios.post('https://yourserverurl.com/register', { email: this.email, password: this.password, recaptchaToken: recaptchaToken }) }, validate () { const self = this self.$validator.validateAll().then((result) => { if (result) { self.$refs.recaptcha.execute() } }) }, onCaptchaExpired () { this.$refs.recaptcha.reset() } } } </script>
рд╢реБрд░реВ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдЕрдкрдиреЗ рдШрдЯрдХ рдореЗрдВ Vue-Recaptcha рдХрд╛ рдЖрдпрд╛рдд рдХрд┐рдпрд╛:
import VueRecaptcha from 'vue-recaptcha' ... components: { VueRecaptcha },
рдЕрдЧрд▓рд╛, рд╣рдордиреЗ рдбреЗрдЯрд╛ рдореЗрдВ рд╕рд╛рдЗрдЯрдХреА рд╕рдВрдкрддреНрддрд┐ рдШреЛрд╖рд┐рдд рдХреА () рдШрдЯрдХ:
data () { return { ... sitekey: ' SITE KEY' } },
рд╣рдорд╛рд░реЗ рдлреЙрд░реНрдо рдореЗрдВ Vue-Recaptcha рдШрдЯрдХ рдЬреЛрдбрд╝реЗрдВ:
<vue-recaptcha ref="recaptcha" size="invisible" :sitekey="sitekey" @verify="register" @expired="onCaptchaExpired" />
рдХреИрдкреНрдЪрд╛ рдХреЗ рд╕рдлрд▓ рд╕рдорд╛рдкрди рдкрд░ рд░рдЬрд┐рд╕реНрдЯрд░ рд╡рд┐рдзрд┐ рдХреЛ рдмреБрд▓рд╛рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдЬрдмрдХрд┐ рд╕рдордп рд╕реАрдорд╛ рд╕рдорд╛рдкреНрдд рд╣реЛрдиреЗ рдкрд░ рдХреИрдкреНрдЪрд╛ рдХреА рд╕рдорд╛рдкреНрддрд┐ рдкрд░ рдХреЙрд▓ рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
OnCaptchaExpired рд╡рд┐рдзрд┐ рдХреИрдкреНрдЪрд╛ рдХреЛ рдкреБрдирд░рд╛рд░рдВрдн рдХрд░рддрд╛ рд╣реИ:
onCaptchaExpired () { this.$refs.recaptcha.reset() }
рдлреЙрд░реНрдо рдкрд░ рд╣реА, рд╣рдо @ submit.prevent = "validate" рдИрд╡реЗрдВрдЯ рдЬреЛрдбрд╝рддреЗ рд╣реИрдВ, рдЬреЛ рдлреЙрд░реНрдо рд╕рдмрдорд┐рдЯ рд╣реЛрдиреЗ рдкрд░ рд╡реИрджреНрдп рд╡рд┐рдзрд┐ рдХреЛ рдЯреНрд░рд┐рдЧрд░ рдХрд░рддрд╛ рд╣реИред
validate () { this.$refs.recaptcha.execute() }
рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рдирд┐рдореНрдирд╛рдиреБрд╕рд╛рд░ рд╡рд░реНрдгрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ:
- рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдиреЗ рдбреЗрдЯрд╛ рджрд░реНрдЬ рдХрд┐рдпрд╛ рдФрд░ рд╕рд╛рдЗрди рдЕрдк рдмрдЯрди рдкрд░ рдХреНрд▓рд┐рдХ рдХрд┐рдпрд╛, рд╕рддреНрдпрд╛рдкрди () рдлрд╝рдВрдХреНрд╢рди рдХреЛ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
- рдорд╛рдиреНрдп () рдлрд╝рдВрдХреНрд╢рди рдХреИрдкреНрдЪрд╛ рд╢реБрд░реВ рдХрд░рддрд╛ рд╣реИ, рдЕрдЧрд░ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдЗрд╕реЗ рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рдкрд╛рд╕ рдХрд░рддрд╛ рд╣реИ, рддреЛ рд░рдЬрд┐рд╕реНрдЯрд░ рд╡рд┐рдзрд┐ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред
рд░рдЬрд┐рд╕реНрдЯрд░ рд╡рд┐рдзрд┐ рдореЗрдВ, рд╣рдореЗрдВ рдПрдХ рд░рд┐рдХреИрдкреНрдЯрдЪреЛрдХреЗрди рдорд┐рд▓рддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рджреНрд╡рд╛рд░рд╛ рджрд░реНрдЬ рдХрд┐рдП рдЧрдП рдбреЗрдЯрд╛ рдХреЗ рд╕рд╛рде рд╕рд░реНрд╡рд░ рдХреЛ рднреЗрдЬрдирд╛ рд╣реЛрдЧрд╛:
register (recaptchaToken) { axios.post('https://yourserverurl.com/register', { email: this.email, password: this.password, recaptchaToken: recaptchaToken }) }
рдЗрд╕ рдкрд░ рдлреНрд░рдВрдЯ-рдПрдВрдб рдХреЗ рд╕рд╛рде рд╣рдорд╛рд░рд╛ рдХрд╛рдо рдкреВрд░рд╛ рд╣реЛ рдЧрдпрд╛ рд╣реИред ReCAPTCHA рд╕рдлрд▓рддрд╛рдкреВрд░реНрд╡рдХ рд╕реНрдерд╛рдкрд┐рдд рдФрд░ рдЪрд▓ рд░рд╣рд╛ рд╣реИред
PS рдпрджрд┐ рдЖрдк рдХрдИ рдШрдЯрдХреЛрдВ рдореЗрдВ рдХреИрдкреНрдЪрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдЬрд╛ рд░рд╣реЗ рд╣реИрдВ, рддреЛ рд╕рд╛рдЗрдЯ рдХреЛ .env рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рд░рдЦрдирд╛ рдФрд░ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрд╕реЗ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рд╕рдмрд╕реЗ рдЕрдЪреНрдЫрд╛ рд╣реИ ред
data () { return { ... sitekey: process.env.VUE_APP_RECAPTCHA_TOKEN } },
рдЪрд░рдг # 3: рд╕рддреНрдпрд╛рдкрди рдХрд╛ рд╕рдорд░реНрдерди рдХрд░реЗрдВред рд▓рд╛рд░рд╡реЗрд▓ рдФрд░ рд▓реБрдореЗрди рдкрд░ рдорд╛рдиреНрдпрдХрд░рдг рдЙрджрд╛рд╣рд░рдг
рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреЛ рд╕рд░реНрд╡рд░ рдкрд░ рд╕рддреНрдпрд╛рдкрди рдХрд░рдирд╛ рдмрд╣реБрдд рд╕рд░рд▓ рд╣реИред рдЪрд▓реЛ рд▓рд╛рд░рд╡реЗрд▓ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд╕рд╛рде рд╢реБрд░реВ рдХрд░рддреЗ рд╣реИрдВред
1) рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдлрд╝реЛрд▓реНрдбрд░ рдореЗрдВ, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рд╕рд╛рдордЧреНрд░реА рдХреЗ рд╕рд╛рде рдПрдХ recaptcha.php рдлрд╝рд╛рдЗрд▓ рдмрдирд╛рдПрдВ:
<?php return [ 'enabled' => env('RECAPTCHA_ENABLED', true), 'key' => env('RECAPTCHA_SITE_KEY'), 'secret' => env('RECAPTCHA_SECRET_KEY'), ];
2) рдЙрд╕рдХреЗ рдмрд╛рдж, рдЪрд░ рдХреЛ .env рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдЬреЛрдбрд╝реЗрдВ:
RECAPTCHA_ENABLED=FALSE RECAPTCHA_SITE_KEY=_SITE_KEY RECAPTCHA_SECRET_KEY=_SECRET_KEY
3) Google API рдЕрдиреБрд░реЛрдз рднреЗрдЬрдиреЗ рдореЗрдВ рд╕рдХреНрд╖рдо рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП GuzzleHttp рд╕реНрдерд╛рдкрд┐рдд рдХрд░реЗрдВ:
composer require guzzlehttp/guzzle
4) рдирд┐рдпрдВрддреНрд░рдХ рдореЗрдВ, CheckRecaptcha рд╡рд┐рдзрд┐ рдЬреЛрдбрд╝реЗрдВ:
protected function checkRecaptcha($token, $ip) { $response = (new Client)->post('https://www.google.com/recaptcha/api/siteverify', [ 'form_params' => [ 'secret' => config('recaptcha.secret'), 'response' => $token, 'remoteip' => $ip, ], ]); $response = json_decode((string)$response->getBody(), true); return $response['success']; }
рдЗрд╕ рд╡рд┐рдзрд┐ рдореЗрдВ, рд╣рдо https://www.google.com/recaptcha/api/siteverify рдкрд░ POST рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЕрдкрдирд╛ рдЯреЛрдХрди (рдЬрд┐рд╕реЗ рд╣рдореЗрдВ рдлреНрд░рдВрдЯреЗрдВрдб рд╕реЗ рдкреНрд░рд╛рдкреНрдд рд╣реБрдЖ рд╣реИ) рднреЗрдЬрддреЗ рд╣реИрдВ
5) рд░рдЬрд┐рд╕реНрдЯрд░ рд╡рд┐рдзрд┐ рдореЗрдВ (рдЖрдкрдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдирд╛рдо рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдпрд╣ рд╡рд╣ рд╡рд┐рдзрд┐ рд╣реИ, рдЬрд┐рд╕рдХреЗ рд▓рд┐рдП рдЖрдкрдиреЗ рдкреЛрд╕реНрдЯ рдХреЛ рдЕрдиреБрд░реЛрдз рд╕реЗ рднреЗрдЬрд╛ рд╣реИ) рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреЛрдб рдЬреЛрдбрд╝реЗрдВ:
if (config('recaptcha.enabled') && !$this->checkRecaptcha($request->recaptcha_token, $request->ip())) { return return response()->json([ 'error' => 'Captcha is invalid.', ], Response::HTTP_BAD_REQUEST); }
рд╕рдм рдХреБрдЫ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╣реИ!
- рд░рдЬрд┐рд╕реНрдЯрд░ рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╕рдордп, рд╣рдо рдИрдореЗрд▓, рдкрд╛рд╕рд╡рд░реНрдб рдФрд░ recaptcha_token рдкреНрд░рд╛рдкреНрдд рдХрд░рддреЗ рд╣реИрдВред
- рдпрджрд┐ рдкреБрдирд░рд╛рд╡реГрддреНрддрд┐ рд╕рдХреНрд╖рдо рд╣реИ (.env рдлрд╝рд╛рдЗрд▓ рдореЗрдВ, RECAPTCHA_ENABLED рдХрд╛ рдорд╛рди TRUE рд╣реИ),
рд▓рд╛рд░рд╡реЗрд▓ Google API рдЕрдиреБрд░реЛрдз рднреЗрдЬреЗрдЧрд╛ред - рдпрджрд┐ рдЙрддреНрддрд░ рдирд╣реАрдВ рд╣реИ, рддреЛ рд╣рдо рдкрд╛рда рдХреЗ рд╕рд╛рде рдПрдХ рддреНрд░реБрдЯрд┐ рд▓реМрдЯрд╛рддреЗ рд╣реИрдВ: рдХреИрдкреНрдЪрд╛ рдЕрдорд╛рдиреНрдп рд╣реИред
- рдпрджрд┐ рд╕рдХрд╛рд░рд╛рддреНрдордХ рд╣реИ, рддреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдкрдВрдЬреАрдХрд░рдг рдЬрд╛рд░реА рд░рдЦреЗрдВред

рдЯреЛрдХрди рдпрд╛рддреНрд░рд╛ рджреГрд╢реНрдп рдкреНрд░рд╕реНрддреБрддрд┐ред
рдкреВрд░реНрдг рдирд┐рдпрдВрддреНрд░рдХ рдХреЛрдб рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
<?php namespace App\Http\Controllers\Users; use App\Http\Controllers\Controller; use Illuminate\Http\Request; use Illuminate\Http\Response; use GuzzleHttp\Client; class UserController extends Controller { protected function checkRecaptcha($token, $ip) { $response = (new Client)->post('https://www.google.com/recaptcha/api/siteverify', [ 'form_params' => [ 'secret' => config('recaptcha.secret'), 'response' => $token, 'remoteip' => $ip, ], ]); $response = json_decode((string)$response->getBody(), true); return $response['success']; } public function register(Request $request) { $request->validate([ 'email' => 'required|string|email|unique:users|max:255', 'password' => 'required|string|max:32|min:6', 'recaptcha_token' => 'string' ]); if (config('recaptcha.enabled') && !$this->checkRecaptcha($request->recaptcha_token, $request->ip())) { return response()->json([ 'error' => 'Captcha is invalid.', ], Response::HTTP_BAD_REQUEST); }
рд▓реБрдореЗрди рдХреА рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдХреА рдкреБрд╖реНрдЯрд┐
рд▓реБрдореЗрди рдкрд░, рд╣рдо рд▓рд╛рд░рд╡реЗрд▓ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рд╕рдм рдХреБрдЫ рдЙрд╕реА рддрд░рд╣ рдХрд░рддреЗ рд╣реИрдВ, рд╕рд┐рд╡рд╛рдп рдЗрд╕рдХреЗ рдХрд┐ рд╣рдореЗрдВ рдмреВрдЯрд╕реНрдЯреНрд░реИрдк / app.php рдореЗрдВ рдЕрдкрдиреЗ рдХреЙрдиреНрдлрд┐рдЧрд░ ( recaptcha.php ) рдХреЛ рдкрдВрдЬреАрдХреГрдд рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ:
$app->configure('recaptcha');
рдирд┐рд╖реНрдХрд░реНрд╖
рддреЛ, рдЗрд╕ рд▓реЗрдЦ рдореЗрдВ, рдЖрдкрдиреЗ рд╕реАрдЦрд╛ рдХрд┐ рдЕрдкрдиреЗ Vue рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ Google reCAPTCHA рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреИрд╕реЗ рдХрд░реЗрдВред
рдЕрдкрдиреЗ рд╕рдВрд╕рд╛рдзрди рдХреЛ рдмреЙрдЯреНрд╕ рд╕реЗ рдмрдЪрд╛рдиреЗ рдХреЗ рд▓рд┐рдП ReCAPTCHA рдПрдХ рдмреЗрд╣рддрд░реАрди рдлреНрд░реА рдЯреВрд▓ рд╣реИред
рдЕрджреГрд╢реНрдп рдХреИрдкреНрдЪрд╛ рдХреЗ рд╕рд╛рде рдЖрдк рдЖрдЧрдВрддреБрдХреЛрдВ рдХреЛ рдХрд┐рд╕реА рднреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдХреЗ рдмрд┐рдирд╛ рдЬрд╛рдВрдЪ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдХреЛрдбрдкреЗрди рдкрд░ рдПрдХ рд▓реЗрдЦ рд╕реЗ рдЙрджрд╛рд╣рд░рдг рдЖрд╡реЗрджрди
рдЙрдкрдпреЛрдЧ рдХрд┐рдП рдЧрдП рд╕реНрд░реЛрдд:
- https://github.com/DanSnow/vue-recaptcha
- https://developers.google.com/recaptcha/docs/invisible
- https://developers.google.com/recaptcha/docs/verify
- https://security.stackexchange.com/questions/78807/how-does-googles-no-captcha-recaptcha-work