Laravel5.7でreCAPTCHAを導入してみる


需要があるのでreCAPTCHAを導入法を調べました。

参考サイトは[こちら](https://appdividend.com/2018/04/07/laravel-google-recaptcha-tutorial/)。ほぼまんまです。すみません。

## 準備

### Laravelのインストール

割愛してもいいですが、一応。

```bash
composer create-project laravel/laravel recap
```

### reCAPTCHA簡易導入パッケージを入れる

[anhskohbo/no-captcha](https://github.com/anhskohbo/no-captcha)ってやつをみんな使ってるようです。
本家サイトに詳しい導入の方法があります。

```bash
composer require anhskohbo/no-captcha
```

### configファイルの生成

設定ファイルをPublishします。config/captcha.phpが出力されます。

```bash
php artisan vendor:publish --provider="Anhskohbo\NoCaptcha\NoCaptchaServiceProvider"
```

### reCAPTCHAサイトでのキー取得と.envの設定

[Googleサイト](https://www.google.com/recaptcha/admin)で取得します。
Domainはテスト用のドメイン（localhost）と本番用（あれば）を追記しておけばいいでしょう（1ドメイン1行）。

<img width="626" alt="スクリーンショット 2018-10-08 17.46.33.png" src="https://qiita-image-store.s3.amazonaws.com/0/55188/1af8f632-3602-1b22-3a95-4f6b6cbcb533.png">

取得したSite KeyとSecret Keyを登録します。
キーの名前はcaptcha.phpで定義されているので、それに合わせます。

```bash
NOCAPTCHA_SITEKEY=xxxxxxxxxxxxxxx
NOCAPTCHA_SECRET=xxxxxxxxxxxxxxx
```

## 実装

### Router

必要なルートは２つ。reCAPTCHAを表示するページ（recaptcha）とバリデーションするページ（store)。

```php
Route::get('recaptcha', 'RecaptchaController@create');
Route::post('store', 'RecaptchaController@store');
```

### Controller

Controllerは新規に作成。

```bash
php artisan make:Controller RecaptchaController
```

ルートに対応する機能を実装します。

```php
<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;

class RecaptchaController extends Controller
{

    //画面表示
    public function create()
    {
        return view('recaptchacreate');
    }

　　　　　　　　//バリデーション
    public function store(Request $request)
    {
        $request->validate([
            'name' => 'required',
            'email' => 'required|email',
            'password' => 'required|min:6',
            'g-recaptcha-response' => 'required|captcha', //reCAPTCHA評価
        ]);

        return "success";
    }
}
```

### View

以下の2つを追加することで機能します。

#### 標準の初期化コード

```
 {!! NoCaptcha::renderJs() !!}
```

#### 標準のreCAPTCHA表示コード

```
{!! NoCaptcha::display() !!}
```

コード全体。name, email, password, recaptchaの全部が必須要件。

```html:resources/view/recaptcha.blace.php
<html lang="ja">

<head>
    <title>reCAPTCHA in Laravel</title>
    <link rel="stylesheet" href="{{asset('css/app.css')}}">
</head>

<body>
    <div class="container">
        <h2 class="mt-5 text-center">reCAPTCHA in Laravel</h2><br />
        @if ($errors->any())
        <div class="alert alert-danger">
            <ul>
                @foreach ($errors->all() as $error)
                <li>{{ $error }}</li>
                @endforeach
            </ul>
        </div><br/>
        @endif
        <form method="post" action="{{url('store')}}">
            @csrf
            <div class="row">
                <div class="col-md-4"></div>
                <div class="form-group col-md-4">
                    <label for="Name">Name:</label>
                    <input type="text" class="form-control" name="name">
                </div>
            </div>
            <div class="row">
                <div class="col-md-4"></div>
                <div class="form-group col-md-4">
                    <label for="Email">Email:</label>
                    <input type="text" class="form-control" name="email">
                </div>
            </div>
            <div class="row">
                <div class="col-md-4"></div>
                <div class="form-group col-md-4">
                    <label for="Password">Password:</label>
                    <input type="password" class="form-control" name="password">
                </div>
            </div>
            <div class="row">
                <div class="col-md-4"></div>
                <div class="form-group col-md-4">
                    <label for="ReCaptcha">Recaptcha:</label>
                    {!! NoCaptcha::renderJs() !!}
                    {!! NoCaptcha::display() !!}
                </div>
            </div>
            <div class="row">
                <div class="col-md-4"></div>
                <div class="form-group col-md-4">
                    <button type="submit" class="btn btn-primary">Submit</button>
                </div>
            </div>
        </form>
    </div>
    <script src="{{asset('js/app.js')}}"></script>
</body>
</html>
```

### テスト

では試してみます。

```bash
php artisan serve
```

何も入力・選択せずにSubmitとするとreCAPTCHA含めたエラーとなる（もちろんreCAPTCHAのみでもエラー）。

<img width="723" alt="スクリーンショット 2018-10-08 18.33.40.png" src="https://qiita-image-store.s3.amazonaws.com/0/55188/f79ae020-4e5f-5a78-b612-1ffb900a5963.png">