├── CHANGELOG.md ├── LICENSE.md ├── README.md ├── composer.json ├── config └── geetest-captcha.php ├── renovate.json ├── resources └── views │ └── .gitkeep └── src ├── Commands └── GeetestCaptchaCommand.php ├── Facades └── GeetestCaptcha.php ├── GeetestCaptcha.php ├── GeetestCaptchaServiceProvider.php ├── Http └── Middleware │ └── ValidateGeetestCaptcha.php └── Rules └── GeetestCaptchaValidate.php /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to `laravel-geetest-captcha` will be documented in this file. 4 | 5 | ## v0.0.3 - 2024-11-12 6 | 7 | ### What's Changed 8 | 9 | * [fix] Add error handling for empty or missing response by @salahhusa9 in https://github.com/salahhusa9/laravel-geetest-captcha/pull/9 10 | 11 | **Full Changelog**: https://github.com/salahhusa9/laravel-geetest-captcha/compare/v0.0.2...v0.0.3 12 | 13 | ## v0.0.2 - 2024-07-05 14 | 15 | ### What's Changed 16 | 17 | * Support Laravel 9 by @salahhusa9 in https://github.com/salahhusa9/laravel-geetest-captcha/pull/5 18 | * Update dependency phpunit/phpunit to v11 by @renovate in https://github.com/salahhusa9/laravel-geetest-captcha/pull/6 19 | * Fix vertions by @salahhusa9 in https://github.com/salahhusa9/laravel-geetest-captcha/pull/7 20 | 21 | **Full Changelog**: https://github.com/salahhusa9/laravel-geetest-captcha/compare/v0.0.1...v0.0.2 22 | 23 | ## v0.0.1 - 2024-07-05 24 | 25 | ### What's Changed 26 | 27 | * Configure Renovate by @renovate in https://github.com/salahhusa9/laravel-geetest-captcha/pull/1 28 | * Beta by @salahhusa9 in https://github.com/salahhusa9/laravel-geetest-captcha/pull/3 29 | * Update dependabot/fetch-metadata action to v2.2.0 by @renovate in https://github.com/salahhusa9/laravel-geetest-captcha/pull/4 30 | 31 | ### New Contributors 32 | 33 | * @renovate made their first contribution in https://github.com/salahhusa9/laravel-geetest-captcha/pull/1 34 | * @salahhusa9 made their first contribution in https://github.com/salahhusa9/laravel-geetest-captcha/pull/3 35 | 36 | **Full Changelog**: https://github.com/salahhusa9/laravel-geetest-captcha/commits/v0.0.1 37 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) salahhusa9 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Laravel Geetest Captcha, the best alternative to Google reCaptcha 2 | 3 | [![Latest Version on Packagist](https://img.shields.io/packagist/v/salahhusa9/laravel-geetest-captcha.svg?style=flat-square)](https://packagist.org/packages/salahhusa9/laravel-geetest-captcha) 4 | ![laravel](https://img.shields.io/badge/Laravel-9%7C10%7C11-red) 5 | [![GitHub Tests Action Status](https://img.shields.io/github/actions/workflow/status/salahhusa9/laravel-geetest-captcha/run-tests.yml?branch=main&label=tests&style=flat-square)](https://github.com/salahhusa9/laravel-geetest-captcha/actions?query=workflow%3Arun-tests+branch%3Amain) 6 | [![GitHub Code Style Action Status](https://img.shields.io/github/actions/workflow/status/salahhusa9/laravel-geetest-captcha/fix-php-code-style-issues.yml?branch=main&label=code%20style&style=flat-square)](https://github.com/salahhusa9/laravel-geetest-captcha/actions?query=workflow%3A"Fix+PHP+code+style+issues"+branch%3Amain) 7 | [![Total Downloads](https://img.shields.io/packagist/dt/salahhusa9/laravel-geetest-captcha.svg?style=flat-square)](https://packagist.org/packages/salahhusa9/laravel-geetest-captcha) 8 | 9 | Laravel Geetest Captcha is a package that provides a simple way to integrate Geetest Captcha in your Laravel application. 10 | 11 | ![20240705-122929d](https://github.com/user-attachments/assets/24c38b93-817a-43ec-bc30-9cf54736b346) 12 | 13 | 14 | ## Support us 15 | 16 | Does your business depend on our contributions? Reach out and support us on [Github sponsor](https://github.com/sponsors/salahhusa9). All pledges will be dedicated to allocating workforce on maintenance and new awesome stuff. 17 | 18 | ## Installation 19 | 20 | 1. You can install the package via composer: 21 | 22 | ```bash 23 | composer require salahhusa9/laravel-geetest-captcha 24 | ``` 25 | 26 | 2. You need to add `@geetestCaptchaAssets()` in head tag in your layout file: 27 | 28 | ```html 29 | 30 | 31 | 32 | 33 | 34 | 35 | Document 36 | @geetestCaptchaAssets() 37 | 38 | 39 | ... 40 | 41 | 42 | ``` 43 | 44 | 3. Sign up and activate your GeeTest account on the [official website](https://geetest.com) 45 | 4. Create an ID and Key on the dashboard 46 | 5. add GEETEST_ID and GEETEST_KEY in .env file 47 | 48 | ## Usage 49 | ### Use in form 50 | 51 | You can use in form like this: 52 | 53 | In first add `@geetestCaptchaInit('captcha-id')` in footer of page as script tag, `captcha-id` is the id of the captcha div. 54 | 55 | ```html 56 |
57 | @csrf 58 |
59 | 60 | 61 |
62 |
63 | 64 | 65 |
66 |
67 |
68 | 69 |
70 |
71 | 72 |
73 | 74 | @geetestCaptchaInit('captcha-id') 75 | ``` 76 | 77 | and for validation you can use `geetest_captcha` rule in your controller like this: 78 | 79 | ```php 80 | use Salahhusa9\GeetestCaptcha\Rules\GeetestCaptchaValidate; 81 | 82 | public function login(Request $request) 83 | { 84 | $request->validate([ 85 | 'email' => 'required|email', 86 | 'password' => 'required', 87 | 'geetest_captcha' => ['required', new GeetestCaptchaValidate] 88 | ]); 89 | 90 | // your logic 91 | } 92 | ``` 93 | 94 | ### Validate via middleware 95 | 96 | You can use in middleware like this: 97 | ```php 98 | use Salahhusa9\GeetestCaptcha\Http\Middleware\ValidateGeetestCaptcha; 99 | 100 | Route::post('login', [LoginController::class, 'login'])->middleware(ValidateGeetestCaptcha::class); 101 | ``` 102 | 103 | ## Testing 104 | 105 | ```bash 106 | composer test 107 | ``` 108 | 109 | ## Changelog 110 | 111 | Please see [CHANGELOG](CHANGELOG.md) for more information on what has changed recently. 112 | 113 | ## Contributing 114 | 115 | Please see [CONTRIBUTING](CONTRIBUTING.md) for details. 116 | 117 | ## Security Vulnerabilities 118 | 119 | Please review [our security policy](../../security/policy) on how to report security vulnerabilities. 120 | 121 | ## Credits 122 | 123 | - [salahhusa9](https://github.com/salahhusa9) 124 | - [geetest](https://www.geetest.com/en/) 125 | - [All Contributors](../../contributors) 126 | 127 | ## License 128 | 129 | The MIT License (MIT). Please see [License File](LICENSE.md) for more information. 130 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "salahhusa9/laravel-geetest-captcha", 3 | "description": "Laravel GeeTest Captcha for Laravel 9-10-11", 4 | "keywords": [ 5 | "salahhusa9", 6 | "laravel", 7 | "laravel-geetest-captcha", 8 | "captcha", 9 | "geetest-captcha", 10 | "geetest" 11 | ], 12 | "homepage": "https://github.com/salahhusa9/laravel-geetest-captcha", 13 | "license": "MIT", 14 | "authors": [ 15 | { 16 | "name": "salahhusa9", 17 | "email": "salahhusa9@gmail.com", 18 | "role": "Developer" 19 | } 20 | ], 21 | "require": { 22 | "php": "^8.2||^8.0", 23 | "spatie/laravel-package-tools": "^1.0", 24 | "illuminate/contracts": "^11.0||^10.0||^9.0" 25 | }, 26 | "require-dev": { 27 | "nunomaduro/collision": "^8.0||^7.0||^6.0", 28 | "orchestra/testbench": "^9.0||^8.0||^7.0", 29 | "phpunit/phpunit": "^11.0||^10.0||^9.0" 30 | }, 31 | "autoload": { 32 | "psr-4": { 33 | "Salahhusa9\\GeetestCaptcha\\": "src/", 34 | "Salahhusa9\\GeetestCaptcha\\Database\\Factories\\": "database/factories/" 35 | } 36 | }, 37 | "autoload-dev": { 38 | "psr-4": { 39 | "Salahhusa9\\GeetestCaptcha\\Tests\\": "tests/", 40 | "Workbench\\App\\": "workbench/app/" 41 | } 42 | }, 43 | "scripts": { 44 | "post-autoload-dump": "@composer run prepare", 45 | "clear": "@php vendor/bin/testbench package:purge-laravel-geetest-captcha --ansi", 46 | "prepare": "@php vendor/bin/testbench package:discover --ansi", 47 | "build": [ 48 | "@composer run prepare", 49 | "@php vendor/bin/testbench workbench:build --ansi" 50 | ], 51 | "start": [ 52 | "Composer\\Config::disableProcessTimeout", 53 | "@composer run build", 54 | "@php vendor/bin/testbench serve" 55 | ], 56 | "format": "vendor/bin/pint" 57 | }, 58 | "config": { 59 | "sort-packages": true, 60 | "allow-plugins": { 61 | "phpstan/extension-installer": false, 62 | "pestphp/pest-plugin": false 63 | } 64 | }, 65 | "extra": { 66 | "laravel": { 67 | "providers": [ 68 | "Salahhusa9\\GeetestCaptcha\\GeetestCaptchaServiceProvider" 69 | ], 70 | "aliases": { 71 | "GeetestCaptcha": "Salahhusa9\\GeetestCaptcha\\Facades\\GeetestCaptcha" 72 | } 73 | } 74 | }, 75 | "minimum-stability": "dev", 76 | "prefer-stable": true 77 | } 78 | -------------------------------------------------------------------------------- /config/geetest-captcha.php: -------------------------------------------------------------------------------- 1 | comment('All done'); 16 | 17 | return self::SUCCESS; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/Facades/GeetestCaptcha.php: -------------------------------------------------------------------------------- 1 | captcha_id = env('GEETEST_ID'); 18 | $this->captcha_key = env('GEETEST_KEY'); 19 | $this->api_server = 'http://gcaptcha4.geetest.com'; 20 | } 21 | 22 | public function validate($value) 23 | { 24 | $captcha_id = $this->captcha_id; 25 | $captcha_key = $this->captcha_key; 26 | $api_server = $this->api_server; 27 | 28 | if (empty($value)) { 29 | return false; 30 | } 31 | 32 | $value = json_decode($value, true); 33 | // 2.get the verification parameters passed from the front end after verification 34 | $lot_number = $value['lot_number']; 35 | $captcha_output = $value['captcha_output']; 36 | $pass_token = $value['pass_token']; 37 | $gen_time = $value['gen_time']; 38 | 39 | // 3.generate signature 40 | // use standard hmac algorithms to generate signatures, and take the user's current verification serial number lot_number as the original message, and the client's verification private key as the key 41 | // use sha256 hash algorithm to hash message and key in one direction to generate the final signature 42 | $sign_token = hash_hmac('sha256', $lot_number, $captcha_key); 43 | 44 | // 4.upload verification parameters to the secondary verification interface of GeeTest to validate the user verification status 45 | // geetest recommends to put captcha_id parameter after url, so that when a request exception occurs, it can be quickly located in the log according to the id 46 | $query = [ 47 | 'lot_number' => $lot_number, 48 | 'captcha_output' => $captcha_output, 49 | 'pass_token' => $pass_token, 50 | 'gen_time' => $gen_time, 51 | 'sign_token' => $sign_token, 52 | ]; 53 | $url = sprintf($api_server.'/validate'.'?captcha_id=%s', $captcha_id); 54 | $res = $this->post_request($url, $query); 55 | $obj = json_decode($res, true); 56 | $this->validatedData = $obj; 57 | 58 | if (empty($obj) or ! isset($obj['result'])) { 59 | return false; 60 | } 61 | 62 | if ($obj['result'] != 'success') { 63 | return false; 64 | } 65 | 66 | return true; 67 | } 68 | 69 | private function post_request($url, $postdata) 70 | { 71 | $data = http_build_query($postdata); 72 | 73 | $options = [ 74 | 'http' => [ 75 | 'method' => 'POST', 76 | 'header' => 'Content-type: application/x-www-form-urlencoded', 77 | 'content' => $data, 78 | 'timeout' => 5, 79 | ], 80 | ]; 81 | $context = stream_context_create($options); 82 | $result = file_get_contents($url, false, $context); 83 | preg_match('/([0-9])\d+/', $http_response_header[0], $matches); 84 | $responsecode = intval($matches[0]); 85 | if ($responsecode != 200) { 86 | $result = [ 87 | 'result' => 'success', 88 | 'reason' => 'request geetest api fail', 89 | ]; 90 | 91 | return $result; 92 | } else { 93 | return $result; 94 | } 95 | } 96 | 97 | public function getValidatedData() 98 | { 99 | return $this->validatedData; 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /src/GeetestCaptchaServiceProvider.php: -------------------------------------------------------------------------------- 1 | name('laravel-geetest-captcha') 21 | // ->hasConfigFile() 22 | // ->hasViews() 23 | ->hasCommand(GeetestCaptchaCommand::class); 24 | 25 | Blade::directive('geetestCaptchaAssets', function () { 26 | return ''; 27 | }); 28 | 29 | Blade::directive('geetestCaptchaInit', function ($elementId) { 30 | 31 | $html = << 33 | 50 | HTML; 51 | 52 | return $html; 53 | }); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/Http/Middleware/ValidateGeetestCaptcha.php: -------------------------------------------------------------------------------- 1 | input('geetest_captcha'); 13 | 14 | if (! GeetestCaptcha::validate($value)) { 15 | return response()->json(['message' => 'Geetest captcha validation failed'], 422); 16 | } 17 | 18 | return $next($request); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Rules/GeetestCaptchaValidate.php: -------------------------------------------------------------------------------- 1 | translate(); 17 | } 18 | } 19 | --------------------------------------------------------------------------------