在Laravel,加入Google reCAPTCHA來過濾機器人
以下假設都以取得Google reCAPTCHA V3的使用金鑰,若未取得請到Google reCAPTCHA申請
.env
首先,先在.env
中設定加入api位置和金鑰
..............
RECAPTCHA_ENABLE=true
RECAPTCHA_URL=https://www.google.com/recaptcha/api/siteverify
RECAPTCHA_SITE_KEY=your-site-key
RECAPTCHA_SECRET_KEY=your-secret-key
如果伺服器在長城後面的話,可以嘗試使用https://www.recaptcha.net/recaptcha/api/siteverify
替換RECAPTCHA_URL
Blade
在需要驗證的blade中加入以下內容
<form action="/auth/user/login" method="POST">
@csrf
<input type="hidden" name="google_recaptcha_token" id="ctl-recaptcha-token">
......
......
</form>
......
......
<script src="https://www.google.com/recaptcha/api.js?render={{env('RECAPTCHA_SITE_KEY')}}"></script>
<script>
grecaptcha.ready(function() {
grecaptcha.execute('{{env('RECAPTCHA_SITE_KEY')}}').then(function(token) {
document.getElementById('ctl-recaptcha-token').value = token;
});
});
</script>
如果客戶在長城後面的話,可以嘗試使用https://www.recaptcha.net/recaptcha/api.js
Rules
先使用artisan
建立Rule Case或在app/Rules
下新增
$ php artisan make:rule GoogleRecapchaV3Case
Rule created successfully.
如下,串連Google reCAPTCHA api
namespace App\Rules;
use Illuminate\Contracts\Validation\Rule;
use GuzzleHttp\Client;
class GoogleRecapchaV3Case implements Rule
{
/**
* Determine if the validation rule passes.
*
* @param string $attribute
* @param mixed $value
*
* @return bool
*/
public function passes($attribute, $value): bool
{
if (env('RECAPTCHA_ENABLE') == true) {
return $this->verify($value);
}
return true;
}
/**
* Get the validation error message.
*
* @return string
*/
public function message(): string
{
return ':attribute.failed';
}
/**
* Verify token.
*/
private function verify(string $token = null): bool
{
$url = env('RECAPTCHA_URL', 'https://www.google.com/recaptcha/api/siteverify');
$response = (new Client())->request('POST', $url, [
'form_params' => [
'secret' => env('RECAPTCHA_SECRET_KEY'),
'response' => $token,
],
]);
$code = $response->getStatusCode();
$content = json_decode($response->getBody()->getContents());
return $code == 200 && $content->success == true;
}
}
Controller
將app/Rules/GoogleRecapchaV3Case
加入需要驗證的Controller,並使用$request->validate(['google_recaptcha_token' => new GoogleRecapchaV3Case()])
來進行驗證。
以使用者登入為例:
namespace App\Http\Controllers\Auth\Users;
use Illuminate\Http\Request;
............
// Validate Rule
use App\Rules\GoogleRecapchaV3Case;
class LoginController extends Controller
{
...................
protected function validateLogin(Request $request)
{
$request->validate([
$this->username() => 'required|string',
'password' => 'required|string',
'google_recaptcha_token' => ['required', 'string', new GoogleRecapchaV3Case()],
]);
}
................
}
參考資料
勘誤
- env未加入
RECAPTCHA_ENABLE
設定值