この記事では、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の例と非常に似ています。
仕事を始める
したがって、調理を始める前に、材料のリストが必要です。
- Vueのプロジェクト( https://vuejs.org )
- Vueのコンポーネント( https://github.com/DanSnow/vue-recaptcha )
- Google reCAPTCHAスクリプト( https://www.google.com/recaptcha/api.js )
- サーバーにリクエストを送信するAxios( https://www.npmjs.com/package/axios )
- バックエンドからGoogle API( https://github.com/guzzle/guzzle )にリクエストを送信するためのGuzzle HTTP PHPクライアント
- バックエンド
ステップ#1:サイトでreCAPTCHAを使用するためのキーを取得する
Googleウェブサイトでサイトキーとシークレットキーを取得する必要があります : https : //www.google.com/recaptcha/admin#list
ラベルフィールドには何でも書くことができます。
次に、タイプ-Invisible reCAPTCHA badgeを選択します。
captchaを使用する複数のドメインを指定できます。
例として、 yourawesomedomain.comとlocalhostを示しました 。
利用規約に同意して先に進みます。
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>
<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() }
このプロセスは次のように説明できます。
- ユーザーがデータを入力し、[サインアップ]ボタンをクリックすると、検証()関数が呼び出されます。
- 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); }
すべてを使用する準備ができました!
- registerメソッドにアクセスすると、電子メール、パスワード、recaptcha_tokenが取得されます。
- recaptchaが有効になっている場合(.envファイルで、値RECAPTCHA_ENABLEDはTRUE)、
LaravelはGoogle APIリクエストを送信します。 - 答えがいいえの場合、「Captcha is invalid」というテキストを含むエラーを返します。
- 肯定的な場合、ユーザー登録を続行します。
トークントラベル 視覚的なプレゼンテーション。
完全なコントローラーコードは次のようになります。
<?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は、ボットからリソースを保護するための優れた無料ツールです。
目に見えないキャプチャを使用すると、アクションを実行する必要なくビジターをチェックできます。
使用されるソース: