Google reCAPTCHAをVueに接続し、サーバーで応答を検証する


この記事では、Googleのキャプチャ(reCAPTCHA)をVue JSに接続し、サーバーで応答を検証する方法を示します(例としてLaravel / Lumenのバックエンドを使用しますが、検証の原理はすべてのテクノロジーで同じです)。


まえがき


Invisible reCAPTCHAを使用します。
これは目に見えない* captchaであり、システムが必要と判断するまで渡す必要はありません。 サイト管理者は、システムがユーザーに追加の検証を要求するしきい値レベル(セキュリティ設定)を設定できます。


*-ページにreCAPTCHAアイコンがまだ存在している必要があります。



サイト上の目に見えないキャプチャ。


質問/回答


仕事を始める前に、Google reCAPTCHAを使い始めたときに生じた質問に答えたいと思います。


Q:reCAPTCHAの費用はいくらですか?
A:GoogleのReCAPTCHAは無料のツールです。


Q:既にサイトでキャプチャに合格している場合、バックエンドでユーザーの応答を再度確認する必要があるのはなぜですか?
A:サーバーにリクエストを送信すると、次のようなものが送信されます。


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

バックエンドでcaptchaトークンをチェックしない場合、ボットはこのトークンなしでリクエストを単にスパムしたり、ダミーのトークンに置き換えたりすることができます。


Q:反応がありますが、どうすればよいですか?
A:React JSは素晴らしいことです。 ウェブサイトの開発に使用する場合は、 https://github.com/appleboy/react-recaptchaに注意することをお勧めします 。 操作の原理は、Vueの例と非常に似ています。


仕事を始める


したがって、調理を始める前に、材料のリストが必要です。



ステップ#1:サイトでreCAPTCHAを使用するためのキーを取得する


Googleウェブサイトでサイトキーシークレットキーを取得する必要がありますhttps : //www.google.com/recaptcha/admin#list



ラベルフィールドには何でも書くことができます。


次に、タイプ-Invisible reCAPTCHA badgeを選択します。


captchaを使用する複数のドメインを指定できます。
例として、 yourawesomedomain.comlocalhostを示しました


利用規約に同意して先に進みます。



2つのキーが与えられました。安全な場所に保管してください。 後でそれらに戻ります。


ステップ#2:フロントエンド。 captchaをインストールしてフォームに接続する


開始するには、このコードをheadセクションに追加する必要があります。


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

onloadプロパティは、キャプチャを使用する準備ができたことをコンポーネントに伝えます。


次に、完成したコンポーネントを表示し、部分的に分析します。


 <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> 

VeeValidateを使用してフィールドを検証するコンポーネントの例
 <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()コンポーネントでsitekeyプロパティを宣言しました。


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

Vue-Recaptchaコンポーネントをフォームに追加します。


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

registerメソッドはキャプチャが正常に完了すると呼び出され、expiredはキャプチャが期限切れになると呼び出されます。


onCaptchaExpiredメソッドは、 キャプチャを再起動します。


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

フォーム自体に@ submit.prevent = "validate"イベントを追加ます。これは、フォームが送信されたときにvalidateメソッドを起動ます。


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

このプロセスは次のように説明できます。


  1. ユーザーがデータを入力し、[サインアップ]ボタンをクリックすると、検証()関数が呼び出されます。
  2. validate()関数はcaptchaを開始します。ユーザーが成功すると、registerメソッドが呼び出されます。

registerメソッドでは、ユーザーが入力したデータと共にサーバーに送信する必要があるrecaptchaTokenを取得します。


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

これで、フロントエンドとの作業が完了しました。 ReCAPTCHAが正常にインストールされ、実行されています。


PS複数のコンポーネントでcaptchaを使用する場合は、 .envファイルにsitekeyを配置し、 process.envを使用し取得することをお勧めします。


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

ステップ#3:バックエンドの検証。 LaravelとLumenの検証例


サーバーで応答の検証を行うことは非常に簡単です。 Laravelの例から始めましょう。


1) configフォルダーで、次の内容の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) GuzzleHttpをインストールして、Google APIリクエストを送信できるようにします。


 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']; } 

このメソッドでは、POSTメソッドを使用してhttps://www.google.com/recaptcha/api/siteverifyにトークン(フロントエンドから受け取ったトークン)を送信します


5) registerメソッド(名前は異なる場合があります。これはフロントエンドからPOSTリクエストを送信したメソッドです)に次のコードを追加します。


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

すべてを使用する準備ができました!




トークントラベル 視覚的なプレゼンテーション。


完全なコントローラーコードは次のようになります。


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

ルーメンへの応答の検証


Lumenでは、設定( recaptcha.php )をbootstrap / app.phpに登録する必要があることを除いて、Laravelの例と同じことをすべて行います。


 $app->configure('recaptcha'); 

おわりに


したがって、この記事では、VueプロジェクトでGoogle reCAPTCHAを使用する方法を学びました。


ReCAPTCHAは、ボットからリソースを保護するための優れた無料ツールです。
目に見えないキャプチャを使用すると、アクションを実行する必要なくビジターをチェックできます。


codepenに関する記事のサンプルアプリケーション


使用されるソース:


  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/J443370/


All Articles