[Generator] Fingerprinting CAPTCHAs to keep the same image between two
requests (fixes #11)
This commit is contained in:
parent
726f21e2ad
commit
a3ce06f263
|
@ -39,13 +39,26 @@ class CaptchaGenerator {
|
|||
*/
|
||||
public $expiration;
|
||||
|
||||
/**
|
||||
* Random fingerprint
|
||||
* Useful to be able to regenerate exactly the same image
|
||||
* @var array
|
||||
*/
|
||||
public $fingerprint;
|
||||
|
||||
/**
|
||||
* Should fingerprint be used ?
|
||||
* @var boolean
|
||||
*/
|
||||
public $use_fingerprint;
|
||||
|
||||
/**
|
||||
* The captcha code
|
||||
* @var string
|
||||
*/
|
||||
public $value;
|
||||
|
||||
public function __construct($value, $imageFolder, $webPath, $gcFreq, $expiration, $font)
|
||||
public function __construct($value, $imageFolder, $webPath, $gcFreq, $expiration, $font, $fingerprint)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->imageFolder = $imageFolder;
|
||||
|
@ -53,6 +66,8 @@ class CaptchaGenerator {
|
|||
$this->gcFreq = intval($gcFreq);
|
||||
$this->expiration = intval($expiration);
|
||||
$this->font = $font;
|
||||
$this->fingerprint = $fingerprint;
|
||||
$this->use_fingerprint = (bool)$fingerprint;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -80,6 +95,34 @@ class CaptchaGenerator {
|
|||
return $this->generate($width, $height, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random number or the next number in the
|
||||
* fingerprint
|
||||
*/
|
||||
public function rand($min, $max)
|
||||
{
|
||||
if (!is_array($this->fingerprint)) {
|
||||
$this->fingerprint = array();
|
||||
}
|
||||
|
||||
if ($this->use_fingerprint) {
|
||||
$value = current($this->fingerprint);
|
||||
next($this->fingerprint);
|
||||
} else {
|
||||
$value = mt_rand($min, $max);
|
||||
$this->fingerprint[] = $value;
|
||||
}
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the CAPTCHA fingerprint
|
||||
*/
|
||||
public function getFingerprint()
|
||||
{
|
||||
return $this->fingerprint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes all images in the configured folder
|
||||
* that are older than 10 minutes
|
||||
|
@ -106,17 +149,17 @@ class CaptchaGenerator {
|
|||
{
|
||||
$i = imagecreatetruecolor($width,$height);
|
||||
|
||||
$col = imagecolorallocate($i, mt_rand(0,110), mt_rand(0,110), mt_rand(0,110));
|
||||
$col = imagecolorallocate($i, $this->rand(0,110), $this->rand(0,110), $this->rand(0,110));
|
||||
|
||||
imagefill($i, 0, 0, 0xFFFFFF);
|
||||
|
||||
// Draw random lines
|
||||
for ($t=0; $t<10; $t++) {
|
||||
$tcol = imagecolorallocate($i, 100+mt_rand(0,150), 100+mt_rand(0,150), 100+mt_rand(0,150));
|
||||
$Xa = mt_rand(0, $width);
|
||||
$Ya = mt_rand(0, $height);
|
||||
$Xb = mt_rand(0, $width);
|
||||
$Yb = mt_rand(0, $height);
|
||||
$tcol = imagecolorallocate($i, 100+$this->rand(0,150), 100+$this->rand(0,150), 100+$this->rand(0,150));
|
||||
$Xa = $this->rand(0, $width);
|
||||
$Ya = $this->rand(0, $height);
|
||||
$Xb = $this->rand(0, $width);
|
||||
$Yb = $this->rand(0, $height);
|
||||
imageline($i, $Xa, $Ya, $Xb, $Yb, $tcol);
|
||||
}
|
||||
|
||||
|
@ -130,11 +173,11 @@ class CaptchaGenerator {
|
|||
imagettftext($i, $size, 0, ($width-$txt_width)/2, ($height-$txt_height)/2+$size, $col, $font, $this->value);
|
||||
|
||||
// Distort the image
|
||||
$X = mt_rand(0, $width);
|
||||
$Y = mt_rand(0, $height);
|
||||
$Phase=mt_rand(0,10);
|
||||
$Scale = 1.3 + mt_rand(0,10000)/30000;
|
||||
$Amp=1+mt_rand(0,1000)/1000;
|
||||
$X = $this->rand(0, $width);
|
||||
$Y = $this->rand(0, $height);
|
||||
$Phase=$this->rand(0,10);
|
||||
$Scale = 1.3 + $this->rand(0,10000)/30000;
|
||||
$Amp=1+$this->rand(0,1000)/1000;
|
||||
$out = imagecreatetruecolor($width, $height);
|
||||
|
||||
for ($x=0; $x<$width; $x++)
|
||||
|
|
|
@ -128,7 +128,13 @@ class CaptchaType extends AbstractType
|
|||
|
||||
public function buildView(FormView $view, FormInterface $form)
|
||||
{
|
||||
$generator = new CaptchaGenerator($this->generateCaptchaValue(), $this->imageFolder, $this->webPath, $this->gcFreq, $this->expiration, $this->font);
|
||||
$fingerprint = null;
|
||||
|
||||
if ($this->session->has($this->key.'_fingerprint')) {
|
||||
$fingerprint = $this->session->get($this->key.'_fingerprint');
|
||||
}
|
||||
|
||||
$generator = new CaptchaGenerator($this->generateCaptchaValue(), $this->imageFolder, $this->webPath, $this->gcFreq, $this->expiration, $this->font, $fingerprint);
|
||||
|
||||
if ($this->asFile) {
|
||||
$view->set('captcha_code', $generator->getFile($this->width, $this->height));
|
||||
|
@ -137,6 +143,10 @@ class CaptchaType extends AbstractType
|
|||
}
|
||||
$view->set('captcha_width', $this->width);
|
||||
$view->set('captcha_height', $this->height);
|
||||
|
||||
if ($this->keepValue) {
|
||||
$this->session->set($this->key.'_fingerprint', $generator->getFingerprint());
|
||||
}
|
||||
}
|
||||
|
||||
public function getDefaultOptions(array $options = array())
|
||||
|
|
|
@ -41,6 +41,10 @@ class CaptchaValidator implements FormValidatorInterface
|
|||
}
|
||||
|
||||
$this->session->remove($this->key);
|
||||
|
||||
if ($this->session->has($this->key.'_fingerprint')) {
|
||||
$this->session->remove($this->key.'_fingerprint');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in New Issue