Add captcha

This commit is contained in:
Michael RICOIS 2018-03-05 17:05:47 +01:00
parent bec5a21522
commit 2c870b56f4
14 changed files with 301 additions and 14 deletions

View File

@ -34,6 +34,9 @@ function __autoload($className)
return true;
}
if (function_exists('MathCaptcha\mathcaptchaAutoload') && MathCaptcha\mathcaptchaAutoload($className)) {
return true;
}
$className = str_replace(chr(0), '', $className);
$classDir = dirname(__FILE__).'/../classes/';
@ -42,24 +45,23 @@ function __autoload($className)
$file_in_classes = file_exists($classDir.$className.'.php');
// This is a Core class and its name is the same as its declared name
if (substr($className, -4) == 'Core')
if (substr($className, -4) == 'Core') {
require_once($classDir.substr($className, 0, -4).'.php');
else
{
if ($file_in_override && $file_in_classes)
{
}
else {
if ($file_in_override && $file_in_classes) {
require_once($classDir.str_replace(chr(0), '', $className).'.php');
require_once($overrideDir.$className.'.php');
}
elseif (!$file_in_override && $file_in_classes)
{
elseif (!$file_in_override && $file_in_classes) {
require_once($classDir.str_replace(chr(0), '', $className).'.php');
$classInfos = new ReflectionClass($className.((interface_exists($className, false) or class_exists($className, false)) ? '' : 'Core'));
if (!$classInfos->isInterface() && substr($classInfos->name, -4) == 'Core')
eval(($classInfos->isAbstract() ? 'abstract ' : '').'class '.$className.' extends '.$className.'Core {}');
}
elseif ($file_in_override && !$file_in_classes)
elseif ($file_in_override && !$file_in_classes) {
require_once($overrideDir.$className.'.php');
}
}
}

View File

@ -0,0 +1,16 @@
<?php
require_once dirname(__FILE__).'/../../config/config.inc.php';
require_once dirname(__FILE__).'/../../init.php';
session_start();
$mathCaptcha = new MathCaptcha\MathCaptcha();
try {
$mathCaptcha->generate();
$mathCaptcha->output();
}
catch ( MathCaptcha\MathCaptchaException $e ) {
// Here you normally log the error, and you can output an error image
// to notify the user that something went wrong, if you want.
}

View File

@ -1,7 +1,8 @@
<?php
require_once(dirname(__FILE__).'/../../config/config.inc.php');
require_once(dirname(__FILE__).'/../../init.php');
require_once(dirname(__FILE__).'/Reason.php');
require_once dirname(__FILE__).'/../../config/config.inc.php';
require_once dirname(__FILE__).'/../../init.php';
require_once dirname(__FILE__).'/Reason.php';
$controller->preProcess();
$langs = Language::getLanguages();
@ -52,12 +53,18 @@ if (Tools::isSubmit('submitMessage')) {
$fileAttachment['mime'] = $_FILES['fileUpload']['type'];
}
$mathCaptcha = new MathCaptcha\MathCaptcha();
$captcha_ans = Tools::getValue('cans');
$message = Tools::htmlentitiesUTF8(Tools::getValue('message'));
if (Tools::getValue('email2') != '') {
$this->errors[] = Tools::displayError('Invalid');
$errors[] = Tools::displayError('Invalid');
}
elseif ($mathCaptcha->check($captcha_ans) !== true) {
$errors[] = Tools::displayError('Invalid');
}
elseif (preg_match("/\p{Han}+/u", $message)) {
$this->errors[] = Tools::displayError('Invalid message');
$errors[] = Tools::displayError('Invalid message');
}
elseif (!($from = trim(Tools::getValue('from'))) OR !Validate::isEmail($from)) {
$errors[] = Tools::displayError('Invalid e-mail address');

View File

@ -176,10 +176,12 @@
<label for="message">{l s='Message' mod='ant_support_form'}</label>
<textarea id="message" name="message">{if isset($message)}{$message|escape:'htmlall':'UTF-8'|stripslashes}{/if}</textarea>
</p>
<p>
<img src="{$base_dir_ssl}/c.png" alt=""><input type="text" name="cans">
</p>
<p class="submit">
<input type="submit" name="submitMessage" id="submitMessage" value="{l s='Send' mod='ant_support_form'}" class="button_large" onclick="$(this).hide();" />
</p>
</div>
</fieldset>
</form>

View File

@ -56,10 +56,16 @@ class ContactController extends ContactControllerCore {
$fileAttachment['mime'] = $_FILES['fileUpload']['type'];
}
$mathCaptcha = new MathCaptcha\MathCaptcha();
$captcha_ans = Tools::getValue('cans');
$message = Tools::htmlentitiesUTF8(Tools::getValue('message'));
if (Tools::getValue('email2') != '') {
$this->errors[] = Tools::displayError('Invalid');
}
elseif ($mathCaptcha->check($captcha_ans) !== true) {
$this->errors[] = Tools::displayError('Invalid');
}
elseif (preg_match("/\p{Han}+/u", $message)) {
$this->errors[] = Tools::displayError('Invalid message');
}

View File

@ -117,6 +117,9 @@
<label for="message">{l s='Message'}</label>
<textarea id="message" name="message">{if isset($message)}{$message|escape:'htmlall':'UTF-8'|stripslashes}{/if}</textarea>
</p>
<p>
<img src="c.png" alt=""><input type="text" name="cans">
</p>
<p class="submit">
<input type="submit" name="submitMessage" id="submitMessage" value="{l s='Send'}" class="button_large" onclick="$(this).hide();" />
</p>

View File

@ -119,6 +119,9 @@
<label for="message">{l s='Message'}</label>
<textarea id="message" name="message">{if isset($message)}{$message|escape:'htmlall':'UTF-8'|stripslashes}{/if}</textarea>
</p>
<p>
<img src="c.png" alt=""><input type="text" name="cans">
</p>
<p class="submit">
<span class="gradient"><input type="submit" name="submitMessage" id="submitMessage" value="{l s='Send'}" class="exclusive" onclick="$(this).hide();" /></span>
</p>

View File

@ -0,0 +1,41 @@
## Description:
This is a PHP class for generating images with simple mathematical questions (Math CAPTCHAs) to protect the forms of your website from spambots.
## How to Use:
To generate a captcha you simply:
```PHP
session_start();
$mathCaptcha = new MathCaptcha\MathCaptcha();
$mathCaptcha->generate();
$mathCaptcha->output();
```
The `MathCaptcha` class makes use of session variables so you have to call the `session_start()` function before instantiating a `MathCaptcha` object.
You can optionally supply an identifier for the captcha, to the constructor of the `MathCaptcha` class, if you want to use multiple captchas in your website.
To verify the user's answer you simply:
```PHP
session_start();
$mathCaptcha = new MathCaptcha\MathCaptcha();
if ( $mathCaptcha->check($captcha_answer) === true ) {
// Correct answer
}
else {
// Incorrect answer
}
```
If you use more than one captchas in your website you need also to supply the identifier of the captcha, to the constructor of the `MathCaptcha` class.
Check out the `test_form.php` and `math_captcha.php` files for a working example.
## Requirements:
PHP 5, GD 2.0.1 or later (2.0.28 or later is recommended)

View File

@ -0,0 +1,27 @@
<?php
namespace MathCaptcha;
/**
* Autoloader
*/
function mathcaptchaAutoload($className)
{
$prefix = __NAMESPACE__ . '\\';
$prefixLength = strlen($prefix);
if (0 === strpos($className, $prefix))
{
$parts = explode('\\', substr($className, $prefixLength));
$filepath = __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'MathCaptcha' . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $parts) . '.php';
if (is_file($filepath))
{
require $filepath;
return true;
}
}
return false;
}

View File

@ -0,0 +1,21 @@
{
"name": "magkopian/php-math-captcha",
"description": "A simple class for generating and validating math captcha images",
"keywords": ["captcha","math captcha","antispam","captcha class"],
"license": "MIT",
"authors": [
{
"name": "Manolis Agkopian",
"email": "m.agkopian@gmail.com"
}
],
"require": {
"php": ">=5.0.0",
"ext-gd": "*"
},
"autoload": {
"psr-0": {
"MathCaptcha": "src/"
}
}
}

View File

@ -0,0 +1,15 @@
<?php
require_once 'vendor/autoload.php';
session_start();
$mathCaptcha = new MathCaptcha\MathCaptcha();
try {
$mathCaptcha->generate();
$mathCaptcha->output();
}
catch ( MathCaptcha\MathCaptchaException $e ) {
// Here you normally log the error, and you can output an error image
// to notify the user that something went wrong, if you want.
}

View File

@ -0,0 +1,79 @@
<?php
namespace MathCaptcha;
class MathCaptcha
{
private $addNum1;
private $addNum2;
private $answer = null;
private $captchaImg = null;
private $captchaID = 0;
public function __construct( $captchaID = 0 )
{
$this->captchaID = 'math_captcha_' . $captchaID;
// Set the captcha result from last generated captcha and unset it from the session
if ( isset($_SESSION[$this->captchaID]) ) {
$this->answer = $_SESSION[$this->captchaID];
unset($_SESSION[$this->captchaID]);
}
}
public function generate ()
{
$this->addNum1 = rand(0, 10) * rand(1, 3);
$this->addNum2 = rand(0, 10) * rand(1, 3);
// Set the captcha result for current captcha and set it to the session for later check
$_SESSION[$this->captchaID] = $this->answer = $this->addNum1 + $this->addNum2;
// Create a canvas
if ( ($this->captchaImg = @imagecreatetruecolor(99, 19)) === false ) {
throw new MathCaptchaException('Creation of true color image failed');
}
// Allocate black and white colors
$color_black = imagecolorallocate($this->captchaImg, 0, 0, 0);
$color_white = imagecolorallocate($this->captchaImg, 255, 255, 255);
// Make the background of the image white
imagefilledrectangle($this->captchaImg, 0, 0, 99, 19, $color_white);
// Draw the math question on the image using black color
imagestring($this->captchaImg, 10, 2, 2, $this->addNum1 . ' + ' . $this->addNum2 . ' = ', $color_black);
}
public function output ()
{
if ( $this->captchaImg === null ) {
throw new MathCaptchaException('Captcha image has not been generated');
}
header('Content-Disposition: Attachment;filename=captcha.png');
header('Content-Type: image/png');
imagepng($this->captchaImg);
imagedestroy($this->captchaImg);
}
public function check ( $answer )
{
// Check if math captcha has been generated
if ( $this->answer === null ) {
return false;
}
// Validate captcha
if ( $this->answer === (int) trim($answer) ) {
return true;
}
else {
return false;
}
}
}

View File

@ -0,0 +1,4 @@
<?php
namespace MathCaptcha;
class MathCaptchaException extends \Exception {}

View File

@ -0,0 +1,61 @@
<?php
require_once 'vendor/autoload.php';
session_start();
$msg = '';
// Check if form has been submited
if ( isset($_POST['submit']) && !empty($_POST['submit']) ) {
// Check if user answered the question
if ( !isset($_POST['captcha_ans']) || $_POST['captcha_ans'] === '' ) {
$msg = '<span class="error">Please fill the answer to the math question</span>';
}
else {
$mathCaptcha = new MathCaptcha\MathCaptcha();
// Validate the answer
if ( $mathCaptcha->check($_POST['captcha_ans']) === true ) {
// In a real application here you can register/login the user, insert a comment in the database etc
$msg = '<span class="success">SUCCESS</span>';
}
else {
$msg = '<span class="error">You didn\'t answered the question correctly</span>';
}
}
}
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PHP Math Captcha</title>
<style type="text/css">
.error {
color: red;
}
.success {
color: green;
}
</style>
</head>
<body>
<p id="msg"><?php echo $msg; ?></p>
<p>Answer to this simple math question:</p>
<form action="" method="POST">
<img src="captcha.png" alt="">
<input type="text" name="captcha_ans">
<input type="submit" name="submit" value="Submit">
</form>
</body>
</html>