Menghubungkan Google reCAPTCHA ke Vue dan memvalidasi respons di server


Pada artikel ini saya akan menunjukkan cara menghubungkan captcha dari Google (reCAPTCHA) ke Vue JS dan memvalidasi respons di server (saya menggunakan backend pada Laravel / Lumen sebagai contoh, tetapi prinsip validasi sama untuk semua teknologi).


Kata Pengantar


Kami akan menggunakan reCAPTCHA yang tak terlihat .
Ini adalah * captcha yang tidak terlihat, yang tidak perlu diteruskan sampai sistem menganggapnya perlu. Administrator situs dapat menetapkan tingkat ambang (Preferensi Keamanan) di mana sistem akan meminta pengguna untuk menjalani verifikasi tambahan.


* - ikon reCAPTCHA masih harus ada di halaman.



Captcha tak terlihat di situs.


Pertanyaan / jawaban


Sebelum mulai bekerja, saya ingin menjawab pertanyaan yang muncul ketika saya mulai bekerja dengan Google reCAPTCHA.


T: Berapa biaya reCAPTCHA?
A: ReCAPTCHA dari Google adalah alat gratis.


T: Mengapa saya perlu memeriksa respons pengguna di backend lagi jika sudah melewati captcha di situs?
A: Ketika Anda membuat permintaan ke server, Anda mengirim sesuatu seperti ini:


POST /register 1.1 HTTP Host: www.example.com { "email:"user@gmail.com", "password": "supersecret", "recaptcha-token":"01ASJASJFZ_AASD3115..." } 

Jika Anda tidak memeriksa token captcha di backend, bot dapat dengan mudah melakukan spam dengan permintaan TANPA token ini atau menggantinya dengan dummy.


T: Saya bereaksi, apa yang harus saya lakukan?
A: Bereaksi JS adalah hal yang hebat. Jika Anda menggunakannya untuk pengembangan situs web, saya menyarankan Anda untuk memperhatikan https://github.com/appleboy/react-recaptcha . Prinsip operasi sangat mirip dengan contoh dengan Vue.


Mulai bekerja


Jadi, sebelum mulai memasak, kita perlu daftar bahan:



Langkah # 1: Dapatkan kunci untuk menggunakan reCAPTCHA di situs Anda


Kita perlu mendapatkan kunci situs dan kunci rahasia di situs web Google: https://www.google.com/recaptcha/admin#list



Anda dapat menulis apa pun di bidang label.


Selanjutnya, pilih jenis - Lencana reCAPTCHA tak terlihat .


Anda dapat menentukan beberapa domain tempat Anda akan menggunakan captcha.
Sebagai contoh, saya telah menunjukkan domainanda.com dan localhost .


Kami menerima ketentuan penggunaan dan melanjutkan.



Anda telah diberi dua kunci, simpan di tempat yang aman. Kami akan kembali kepada mereka nanti.


Langkah # 2: Frontend. Menginstal dan menghubungkan captcha ke formulir kami


Untuk memulai, kita perlu menambahkan kode ini ke bagian kepala:


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

Properti onload akan memberi tahu komponen kami bahwa captcha siap digunakan.


Selanjutnya saya akan menunjukkan komponen yang sudah selesai dan kami akan menganalisisnya dalam beberapa bagian:


 <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 () { //       // ,   vee validate //       ,   this.$refs.recaptcha.execute() }, onCaptchaExpired () { this.$refs.recaptcha.reset() } } } </script> 

Contoh Komponen Menggunakan VeeValidate untuk Memvalidasi Bidang
 <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> 

Untuk memulainya, kami mengimpor Vue-Recaptcha ke komponen kami:


 import VueRecaptcha from 'vue-recaptcha' ... components: { VueRecaptcha }, 

Selanjutnya, kami mendeklarasikan properti sitekey dalam komponen data ():


 data () { return { ... sitekey: ' SITE KEY' } }, 

Tambahkan komponen Vue-Recaptcha ke formulir kami:


 <vue-recaptcha ref="recaptcha" size="invisible" :sitekey="sitekey" @verify="register" @expired="onCaptchaExpired" /> 

Metode pendaftaran akan dipanggil setelah berhasil menyelesaikan captcha, sementara yang kedaluwarsa akan dipanggil pada saat berakhirnya captcha.


Metode onCaptchaExpired me- restart captcha:


 onCaptchaExpired () { this.$refs.recaptcha.reset() } 

Pada formulir itu sendiri, kami menambahkan acara @ submit.prevent = "validate" , yang memicu metode validasi ketika formulir dikirimkan .


 validate () { this.$refs.recaptcha.execute() } 

Prosesnya dapat digambarkan sebagai berikut:


  1. Pengguna memasukkan data dan mengklik tombol Sign Up, fungsi validate () dipanggil.
  2. Fungsi validate () memulai captcha, jika pengguna berhasil melewatinya, metode register dipanggil.

Dalam metode register, kita mendapatkan recaptchaToken , yang harus kita kirim ke server bersama dengan data yang dimasukkan pengguna:


 register (recaptchaToken) { axios.post('https://yourserverurl.com/register', { email: this.email, password: this.password, recaptchaToken: recaptchaToken }) } 

Tentang ini pekerjaan kami dengan front-end selesai. ReCAPTCHA berhasil diinstal dan dijalankan.


PS Jika Anda akan menggunakan captcha di beberapa komponen, yang terbaik adalah menempatkan sitekey dalam file .env dan mendapatkannya menggunakan process.env :


 data () { return { ... sitekey: process.env.VUE_APP_RECAPTCHA_TOKEN } }, 

Langkah # 3: validasi backend. Contoh validasi pada Laravel dan Lumen


Membuat validasi respons di server sangat sederhana. Mari kita mulai dengan contoh Laravel.


1) Di folder config , buat file recaptcha.php dengan konten berikut:


 <?php return [ 'enabled' => env('RECAPTCHA_ENABLED', true), 'key' => env('RECAPTCHA_SITE_KEY'), 'secret' => env('RECAPTCHA_SECRET_KEY'), ]; 

2) Setelah itu, tambahkan variabel ke file .env :


 RECAPTCHA_ENABLED=FALSE RECAPTCHA_SITE_KEY=_SITE_KEY RECAPTCHA_SECRET_KEY=_SECRET_KEY 

3) Instal GuzzleHttp untuk dapat mengirim permintaan Google API:


 composer require guzzlehttp/guzzle 

4) Di controller, tambahkan metode 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']; } 

Dalam metode ini, kami mengirim token kami (yang kami terima dari frontend) menggunakan metode POST ke https://www.google.com/recaptcha/api/siteverify


5) Dalam metode register (dalam kasus Anda, nama mungkin berbeda, ini adalah metode yang Anda kirim permintaan POST dari frontend) tambahkan kode berikut:


 if (config('recaptcha.enabled') && !$this->checkRecaptcha($request->recaptcha_token, $request->ip())) { return return response()->json([ 'error' => 'Captcha is invalid.', ], Response::HTTP_BAD_REQUEST); } 

Semuanya siap digunakan!


  • Saat mengakses metode pendaftaran, kami mendapatkan email, kata sandi, dan recaptcha_token.
  • Jika recaptcha diaktifkan (dalam file .env, nilai RECAPTCHA_ENABLED adalah BENAR),
    Laravel akan mengirim permintaan Google API.
  • Jika jawabannya tidak, kami mengembalikan kesalahan dengan teks: Captcha tidak valid.
  • Jika positif, lanjutkan pendaftaran pengguna.


Perjalanan Token Presentasi visual.


Kode pengontrol penuh akan terlihat seperti ini:


 <?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); } //  .  ... } } 

Validasi respons terhadap Lumen


Pada Lumen, kami melakukan semuanya dengan cara yang sama seperti pada contoh Laravel, kecuali bahwa kami perlu mendaftarkan konfigurasi kami ( recaptcha.php ) di bootstrap / app.php :


 $app->configure('recaptcha'); 

Kesimpulan


Jadi, dalam artikel ini, Anda belajar cara menggunakan Google reCAPTCHA dalam proyek Vue Anda.


ReCAPTCHA adalah alat gratis yang bagus untuk melindungi sumber daya Anda dari bot.
Dengan captcha yang tidak terlihat, Anda dapat memeriksa pengunjung tanpa mengharuskan mereka untuk mengambil tindakan apa pun.


Contoh aplikasi dari artikel di codepen


Sumber yang digunakan:


  1. https://github.com/DanSnow/vue-recaptcha
  2. https://developers.google.com/recaptcha/docs/invisible
  3. https://developers.google.com/recaptcha/docs/verify
  4. https://security.stackexchange.com/questions/78807/how-does-googles-no-captcha-recaptcha-work

Source: https://habr.com/ru/post/id443370/


All Articles