laravel9 + recaptcha(v3)した時のメモ

## 参考記事

https://idealive.jp/blog/2019/11/15/laravel-%E3%81%A7-recaptcha/

https://github.com/ARCANEDEV/noCAPTCHA/blob/master/_docs/3-Usage.md

## 概要
フォームから悪意のあるリクエストが飛んでくる。
reCaptcha(v2)は設定していたがどうにも通過される。
ので、
v2→v3に上げた手順を残しておく。

## 対応方法
これに対する対応方法はいくつかあり
reCaptchaをv3にするというのはその中の１つである。

https://qiita.com/Masataka_Sugia/items/96b3095161d6280661e9

## 動作環境
- php-fpm8*
- laravel9
- arcanedev/no-captcha:13.0.0
    - https://github.com/ARCANEDEV/noCAPTCHA

## 手順
### composerパッケージをインストールする
```
$ composer require arcanedev/no-captcha
$ php artisan vendor:publish --provider="Arcanedev\NoCaptcha\NoCaptchaServiceProvider"
```
設定ファイル(config/no-captcha.php)が作成される
```diff_php
<?php

return [

    /* -----------------------------------------------------------------
     |  Credentials
     | -----------------------------------------------------------------
     */

    'secret'  => env('NOCAPTCHA_SECRET', 'no-captcha-secret'),
    'sitekey' => env('NOCAPTCHA_SITEKEY', 'no-captcha-sitekey'),

    /* -----------------------------------------------------------------
     |  Version
     | -----------------------------------------------------------------
     |  Supported: v3, v2
     */

    'version' => 'v3',

    /* -----------------------------------------------------------------
     |  Localization
     | -----------------------------------------------------------------
     */

-    'lang' => null,
+    'lang' => 'jp',

    /* -----------------------------------------------------------------
     |  Skip IPs
     | -----------------------------------------------------------------
     */

    'skip-ips' => [
        // 127.0.0.1
    ],

];

```

### reCaptchaを設定する
https://www.google.com/recaptcha/about/
![スクリーンショット 2022-11-16 10.33.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346005/59c4ac5d-e682-2a31-395c-c9f07d34ebe0.png)
![スクリーンショット 2022-11-16 10.35.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346005/ad914f54-eb03-baa5-b944-1ecf68782831.png)

- ラベル
    - なんでもいい
- ドメイン
    - localで確認するためにlocalhost入れとく
- オーナー
    - 自分と他の管理者入れとくといい

![スクリーンショット 2022-11-16 10.38.24.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/346005/620296d2-1666-0699-0afb-24498db899a6.png)

### Laravel側
#### .env
```.env
# reCAPTCHAのサイトキー
NOCAPTCHA_SITEKEY=サイトキー
# reCAPTCHAのシークレットキー
NOCAPTCHA_SECRET=シークレットキー
```

#### no-captcha設定
```diff_r:config/no-captcha.php
- 'version' => 'v2',
+ 'version' => 'v3',
```

#### blade
```php:form.blade.php
<form method="POST" action="{{ route('login') }}">
    @csrf
    (省略)
    <input type="submit" value="送信" id="submitButton">

    {!! no_captcha()->input() !!}
</form>

{!! no_captcha()->script() !!}
{!! no_captcha()->getApiScript() !!}

<script>
    document.querySelector('#submitButton').addEventListener('click', (event) => {
        event.preventDefault();
        
        grecaptcha.ready(function() {
            grecaptcha.execute('{{config('no-captcha.sitekey')}}', {action: 'submit'}).then(function(token) {
                //// submitするデータにtokenを追加
                document.querySelector('#g-recaptcha-response').value = token;
                document.querySelector('form').submit();
            });
        });
    });
</script>
```

#### バリデーション(FormRequest)
```diff_php
+ use Arcanedev\NoCaptcha\Rules\CaptchaRule;

public function rules()
{
    $rules = [
        'name'     => 'required',
        'kana'     => 'required',
+       'g-recaptcha-response' => ['required', new CaptchaRule]
    ];

    return $rules;
}

public function messages()
{
    $messages = [
        'name.required'                 => '名前は必ず入力してください。',
        'kana.required'                 => 'フリガナは必ず入力してください。',
+       'g-recaptcha-response.required' => 'reCaptchaのtokenがありません。',
+       'g-recaptcha-response.captcha'  => 'reCaptchaによって認証されませんでした',
    ];

    return $messages;
}
```

終わり。