maxsky / php-captcha
v1.0.0
2025-02-17 10:28 UTC
Requires
- php: ^7.2.5|^8.0
- ext-curl: *
- ext-json: *
- guzzlehttp/guzzle: ^7.0
Requires (Dev)
- phpunit/phpunit: ^8.0|^9.0
This package is auto-updated.
Last update: 2025-02-17 12:46:41 UTC
README
Support Google reCaptcha, Cloudflare Turnstile, hCaptcha, Vaptcha validate.
Install
composer require maxsky/php-captcha
Simple usage
Google Recaptcha
$token = 'Recaptcha_Response_Value_From_Request'; // g-recaptcha-response // $clientIp = 'Request_Client_IP'; // optional $params = [ 'secret' => 'Your_Recaptcha_Verify_Key', ]; try { $result = CaptchaService::init($params)->recaptcha($token)->verify(); // $result = CaptchaService::init($params)->recaptcha($token, $clientIp)->verify(); } catch (\Exception $e) { // Request or Response error // \MaxSky\Captcha\Exceptions\CaptchaRequestException // \MaxSky\Captcha\Exceptions\CaptchaResponseException } var_dump($result);
Value example:
array (size=4) 'success' => boolean true 'challenge_ts' => string '2025-02-17T08:57:28Z' (length=20) 'hostname' => string '127.0.0.1' (length=9) 'score' => float 0.9
Cloudflare Turnstile
$token = 'Turnstile_Response_Value_From_Request'; // cf-turnstile-response $clientIpOptional = 'Request_Client_IP'; // optional $params = [ 'secret' => 'Your_Turnstile_Verify_Key' ]; $result = CaptchaService::init($params)->turnstile($token, $clientIpOptional)->verify(); var_dump($result);
Value example:
array (size=7) 'success' => boolean true 'error-codes' => array (size=0) empty 'challenge_ts' => string '2025-02-17T08:59:11.241Z' (length=24) 'hostname' => string '127.0.0.1' (length=9) 'action' => string '' (length=0) 'cdata' => string '' (length=0) 'metadata' => array (size=1) 'interactive' => boolean false
Hcaptcha
// $params & $token same as recaptcha & turnstile $result = CaptchaService::init($params)->hcaptcha($token, $clientIpOptional)->verify(); var_dump($result);
Value example:
array (size=3) 'success' => boolean true 'challenge_ts' => string '2025-02-17T09:03:43.000000Z' (length=27) 'hostname' => string '127.0.0.1' (length=9)
Vaptcha
$token = 'Vaptcha_Response_Token_From_Request'; // vaptcha_token $server = 'Vaptcha_Response_Server_From_Request'; // vaptcha_server $clientIp = 'Request_Client_IP'; // Required $params = [ 'id' => 'Your_Vaptcha_VID', 'secretkey' => 'Your_Vaptcha_Key', 'scene' => 0, // scene ID, default 0 'server' => $server ]; $result = CaptchaService::init($params)->vaptcha($token, $clientIp)->verify(); var_dump($result);
Value example:
array (size=3) 'msg' => string 'success' (length=7) 'success' => int 1 'score' => int 90
Compatible usage
Example by Laravel Framework
1. Create config file
config/captcha.php
file
<?php return [ 'enable' => (bool)env('ADMIN_ENABLE_LOGIN_CAPTCHA', false), 'login' => [ 'type' => env('ADMIN_CAPTCHA_TYPE'), ], 'provider' => [ 'recaptcha' => [ 'key' => env('GOOGLE_RECAPTCHA_CLIENT_KEY'), 'secret' => env('GOOGLE_RECAPTCHA_SERVER_SECRET'), 'threshold' => (float)env('GOOGLE_RECAPTCHA_VERIFY_THRESHOLD', 0.5) ], 'turnstile' => [ 'key' => env('CLOUDFLARE_TURNSTILE_CLIENT_KEY'), 'secret' => env('CLOUDFLARE_TURNSTILE_SERVER_SECRET'), ], 'hcaptcha' => [ 'key' => env('HCAPTCHA_CLIENT_KEY'), 'secret' => env('HCAPTCHA_SERVER_SECRET'), ], 'vaptcha' => [ 'key' => env('VAPTCHA_VID'), 'secret' => env('VAPTCHA_KEY'), 'scene' => (int)env('VAPTCHA_SCENE', 0), 'score' => (int)env('VAPTCHA_VERIFY_SCORE', 80) ] ] ];
2. Create environment config
.env
file
ADMIN_ENABLE_LOGIN_CAPTCHA=true # Values: recaptcha | turnstile | hcaptcha | vaptcha ADMIN_CAPTCHA_TYPE=recaptcha GOOGLE_RECAPTCHA_CLIENT_KEY= GOOGLE_RECAPTCHA_SERVER_SECRET= GOOGLE_RECAPTCHA_VERIFY_THRESHOLD=0.5 CLOUDFLARE_TURNSTILE_CLIENT_KEY= CLOUDFLARE_TURNSTILE_SERVER_SECRET= HCAPTCHA_CLIENT_KEY= HCAPTCHA_SERVER_SECRET= VAPTCHA_VID= VAPTCHA_KEY= VAPTCHA_SCENE=0
3. Controller verify captcha
class AuthController { // define a response fields map constant private const CAPTCHA_RESPONSE_NAME = [ 'recaptcha' => 'g-recaptcha-response', 'turnstile' => 'cf-turnstile-response', // if your js link not set recaptchacompat param off like under example, // hCaptcha will be use 'g-recaptcha-response' as param name same as Google reCaptcha. // https://js.hcaptcha.com/1/api.js?hl=zh-CN&recaptchacompat=off 'hcaptcha' => 'h-captcha-response', 'vaptcha' => 'vaptcha_token' ]; public function login(Request $request) { if (config('captcha.enable')) { $captchaType = config('captcha.login.type'); if ($captchaType) { $token = (string)$request->post(self::CAPTCHA_RESPONSE_NAME[$captchaType]); if (!$token) { // response no challenge data error } $secret = config("captcha.provider.$captchaType.secret"); if ($captchaType === 'vaptcha') { $server = (string)$request->post('vaptcha_server'); if (!$server) { // response no challenge data error } $params = [ 'id' => config("captcha.provider.$captchaType.key"), 'secretkey' => $secret, 'scene' => config('captcha.provider.vaptcha.scene'), 'server' => $server ]; } else { $params = [ 'secret' => $secret ]; } try { $result = CaptchaService::init($params)->{$captchaType}($token, $request->ip())->verify(); if (!$result || !$result['success']) { Log::warning("$captchaType verify failed.", [ 'UA' => $request->userAgent(), 'IP' => $request->ip() ]); Log::warning("$captchaType verify result.", $result); // response challenge failed error } } catch (CaptchaRequestException|CaptchaResponseException $e) { // response verify request or response error } } else { // not supported type } } // TODO: do account login verify } }