Laravel5.8 Vue.js 環境にGoogle reCAPTCHA v2を実装する

Laravel5.8 Vue.js 環境にGoogle reCAPTCHA v2を実装する

Laravel5.8 Vue.js 環境にGoogle reCAPTCHA v2を実装する

下準備

reCAPTCHA
reCAPTCHA is a security service that protects your websites from fraud and abuse.

から登録をする。(ローカル環境で実行したければ、ローカルで動かす用のドメインを登録する)

hostsに

127.0.0.1 koooohe.development

と書いてkooooohe.developmentを登録するなど。

.env

.envに取得した、SITE_KEYとSECRET_KEYを書いていく。

MIX_RECAPTCHA_KEY=XXXXXX
RECAPTCHA_SECRET=XXXXXX

MIXというprefixをつけておくと、Vue.jsからも読み込めるようになる。

Compiling Assets (Mix) - Laravel - The PHP Framework For Web Artisans

Vue.js

reCAPTCHAの情報を取得する

recaptcha_site_key() {
  return process.env.MIX_RECAPTCHA_KEY;
}

といった感じで、.envの内容を取得する。

そして、recaptchaをVue.jsで使うためのpluginをinstall

yarn add vue-recaptcha

created methodで最初に、reCAPRCHA必要な情報を読み込むscriptタグを作成

components: { VueRecaptcha },
created() {        
  let recaptchaScript = document.createElement('script');  
  recaptchaScript.setAttribute('src','https://www.google.com/recaptcha/api.js?onload=vueRecaptchaApiLoaded&render=explicit');
  document.head.appendChild(recaptchaScript); 
},

そして、HTMLを記述

<template>    
  <vue-recaptcha class="g-recaptcha"
                 ref="recaptcha"     
                 :sitekey="recaptcha_site_key"
                 @verify="onVerify"
                 @expired="onExpired"/>
</template>

そして、ライブラリで用意されているmethodを準備する。

このrecaptcha_tokenをサーバに投げるのである。

data() {
  return {    recaptcha_token: '',  }
  },
  methods: {
  onVerify(response) {
  this.recaptcha_token = response;
  },
  onExpired() {
    this.recaptcha_token = ''; //レスポンスのトークンを空に戻す
  },
  resetRecaptcha() {
  this.$refs.recaptcha.reset();
  }}

POSTはこんな感じで適当に各自の実装に合わせてください。

このtokenとは別に本来ならpasswordとemailなども送ると思います。

axios
.post('/api/login', {token:this.recaptcha_token})
.then(response => {})axios
.post('/api/login', {token:this.recaptcha_token})
.then(response => {})

Laravel

Guzzleをinstall

composer require guzzlehttp/guzzle

app/Validation/ReCaptcha.phpを作成

これで、validtionをしていく。

<?phpnamespace App\Validators;use GuzzleHttp\Client;
  class ReCaptcha{
    public function validate($attribute, $value, $parameters, $validator)
    {
        $client = new Client;
        $response = $client->post(
            'https://www.google.com/recaptcha/api/siteverify',
            [
                'form_params' =>
                [
                    'secret' => env('RECAPTCHA_SECRET'),
                    'response' => $value
                ]
            ]
        );
        $body = json_decode((string) $response->getBody());
        return $body->success;
    }
}

app/Providers/AppServiceProvider.phpに追加

<?phpnamespace App\Providers;use Illuminate\Support\ServiceProvider;
useApp\Validation\CustomValidator;
class AppServiceProvider
extends ServiceProvider{
  /**
  * Bootstrap any application services.
  *
  * @return void
  */
  public function boot()
  {
    Validator::extendImplicit('recaptcha','App\\Validators\\ReCaptcha@validate');
  }_/**
  * Register any application services.
  *
  * @return void
  */
  public function register()
  {
    //
  }}

extendではなく、extedImplictを使うことによって、暗黙のrequiredになる。(valueが空でもこの関数が呼ばれる)

Ruleを追加

/**
*
Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
  return [
    'token' => [
      'recaptcha'
    ]
  ];
}

もしうまく動かなければ

compser dumpautoload

を実行する。

参考

https://laravel.com/docs/5.7/mix#environment-variables
https://medium.com/@patrickcurl/using-laravel-env-variables-inside-vue-js-components-29faa9a344c5
https://codeday.me/jp/qa/20190301/341325.html
https://blog.capilano-fw.com/?p=3545
https://medium.com/@dennissmink/laravel-google-recaptcha-a0e2d8b2d03b