[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;
|
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
|
* The captcha code
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
public $value;
|
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->value = $value;
|
||||||
$this->imageFolder = $imageFolder;
|
$this->imageFolder = $imageFolder;
|
||||||
|
@ -53,6 +66,8 @@ class CaptchaGenerator {
|
||||||
$this->gcFreq = intval($gcFreq);
|
$this->gcFreq = intval($gcFreq);
|
||||||
$this->expiration = intval($expiration);
|
$this->expiration = intval($expiration);
|
||||||
$this->font = $font;
|
$this->font = $font;
|
||||||
|
$this->fingerprint = $fingerprint;
|
||||||
|
$this->use_fingerprint = (bool)$fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -80,6 +95,34 @@ class CaptchaGenerator {
|
||||||
return $this->generate($width, $height, true);
|
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
|
* Deletes all images in the configured folder
|
||||||
* that are older than 10 minutes
|
* that are older than 10 minutes
|
||||||
|
@ -106,17 +149,17 @@ class CaptchaGenerator {
|
||||||
{
|
{
|
||||||
$i = imagecreatetruecolor($width,$height);
|
$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);
|
imagefill($i, 0, 0, 0xFFFFFF);
|
||||||
|
|
||||||
// Draw random lines
|
// Draw random lines
|
||||||
for ($t=0; $t<10; $t++) {
|
for ($t=0; $t<10; $t++) {
|
||||||
$tcol = imagecolorallocate($i, 100+mt_rand(0,150), 100+mt_rand(0,150), 100+mt_rand(0,150));
|
$tcol = imagecolorallocate($i, 100+$this->rand(0,150), 100+$this->rand(0,150), 100+$this->rand(0,150));
|
||||||
$Xa = mt_rand(0, $width);
|
$Xa = $this->rand(0, $width);
|
||||||
$Ya = mt_rand(0, $height);
|
$Ya = $this->rand(0, $height);
|
||||||
$Xb = mt_rand(0, $width);
|
$Xb = $this->rand(0, $width);
|
||||||
$Yb = mt_rand(0, $height);
|
$Yb = $this->rand(0, $height);
|
||||||
imageline($i, $Xa, $Ya, $Xb, $Yb, $tcol);
|
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);
|
imagettftext($i, $size, 0, ($width-$txt_width)/2, ($height-$txt_height)/2+$size, $col, $font, $this->value);
|
||||||
|
|
||||||
// Distort the image
|
// Distort the image
|
||||||
$X = mt_rand(0, $width);
|
$X = $this->rand(0, $width);
|
||||||
$Y = mt_rand(0, $height);
|
$Y = $this->rand(0, $height);
|
||||||
$Phase=mt_rand(0,10);
|
$Phase=$this->rand(0,10);
|
||||||
$Scale = 1.3 + mt_rand(0,10000)/30000;
|
$Scale = 1.3 + $this->rand(0,10000)/30000;
|
||||||
$Amp=1+mt_rand(0,1000)/1000;
|
$Amp=1+$this->rand(0,1000)/1000;
|
||||||
$out = imagecreatetruecolor($width, $height);
|
$out = imagecreatetruecolor($width, $height);
|
||||||
|
|
||||||
for ($x=0; $x<$width; $x++)
|
for ($x=0; $x<$width; $x++)
|
||||||
|
|
|
@ -128,7 +128,13 @@ class CaptchaType extends AbstractType
|
||||||
|
|
||||||
public function buildView(FormView $view, FormInterface $form)
|
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) {
|
if ($this->asFile) {
|
||||||
$view->set('captcha_code', $generator->getFile($this->width, $this->height));
|
$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_width', $this->width);
|
||||||
$view->set('captcha_height', $this->height);
|
$view->set('captcha_height', $this->height);
|
||||||
|
|
||||||
|
if ($this->keepValue) {
|
||||||
|
$this->session->set($this->key.'_fingerprint', $generator->getFingerprint());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getDefaultOptions(array $options = array())
|
public function getDefaultOptions(array $options = array())
|
||||||
|
|
|
@ -41,6 +41,10 @@ class CaptchaValidator implements FormValidatorInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->session->remove($this->key);
|
$this->session->remove($this->key);
|
||||||
|
|
||||||
|
if ($this->session->has($this->key.'_fingerprint')) {
|
||||||
|
$this->session->remove($this->key.'_fingerprint');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in New Issue