You are not logged in.

  • Login

1

Wednesday, October 28th 2009, 7:48pm

WCF-EventListener - reCAPTCHA

Hallo,

um auf meiner Plattform das reCAPTCHA nutzen zu können, habe ich mir folgenden EventListener geschrieben:

PHP Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public function execute($eventObj, $className, $eventName) {
	if ($this->useCaptcha === null) {
  	if (isset($eventObj->useCaptcha)) {
    	$this->useCaptcha = $eventObj->useCaptcha;
    	$eventObj->useCaptcha = false;
  	}
  	else {
    	$this->useCaptcha = true;
  	}
	}
 
	if ($this->useCaptcha) {
  	switch ($eventName) {
    	case 'validate':
      	$this->resp = recaptcha_check_answer($this->privateKey, $_SERVER["REMOTE_ADDR"], $_REQUEST["recaptcha_challenge_field"], $_REQUEST["recaptcha_response_field"]);
      	if($this->resp->is_valid) {
  			  $this->useCaptcha = false;
  			} else {
        	$this->error = $this->resp->error;
      	}
    	break;
 
    	case 'assignVariables':
				WCF::getTPL()->assign('captcha', recaptcha_get_html($this->publicKey, $this->error));
    	break;
  	}
	}
	}



Das reCAPTCHA wird auch richtig angezeigt. Wenn dies aber als richtig anerkannt wurde, wird das WCF Captcha nochmal angezeigt.

2

Wednesday, October 28th 2009, 8:21pm

Hi,
damit das WCF Captcha nicht angezeigt wird, musst schon zu beginn $useCaptcha auf false setzen.
Ich weiß die Reihenfolge nicht auswendig, aber es muss geschehen NACHDEM die WCF Klasse in readParameters den Wert auf true gesetzt hat.
Am besten du speicherst dir den Wert in einer anderen Variable: $useRecaptcha

Dementsprechend musst du deine Abfragen der useCaptcha Variable in deinem Script umschreiben.

3

Wednesday, October 28th 2009, 9:24pm

Hi,

danke für die Antwort.
Anscheinend musste ich noch "WCF::getSession()->register('captchaDone', true)" setzen, nachdem das reCAPTCHA richtig ist.

4

Friday, November 13th 2009, 8:00pm

Hi,

nachdem ich das ganze nochmal getestet habe, funktioniert es auf den ersten Blick auch. Aber wenn man nun das Formular absendet, wird das reCAPTCHA auch akzeptiert (verschwindet auch), allerdings gibt das WCF eine Fehlermeldung aus und erst beim nochmaligen Absenden funktioniert es dann.


Gibt es eine eventuelle Problemlösung dazu? Ab Code hat sich nur das erwähnte mit "WCF::getSession()->register('captchaDone', true)" geändert.

5

Saturday, November 14th 2009, 12:09pm

Bei der Programmierung gibt es ein s.g. Geheimniskeitsprinzip (o.ä.)
Du solltest fremden Code also immer als Blackbox sehen. Dass in der Captcha Klasse eine Session Variable namens captchaDone genutzt wird, solltest du nicht für dein Plugin voraussetzen.

Ich habe zwei Postings weiter oben ja mal erläutert, wie ich es machen würde.
Ich glaub der EventListener "readFormParameters" wird nach der Formular Methode "readFormParameters" ausgeführt.
Der EventListener validate jedoch vor der Formular Methode validate.

In der Validate kannst du also mal versuchen ob du das WCF Captcha austrickst, indem du eventObj-> useCaptcha auf false setzt.
Wenn das funktioniert, kannst du einen Schritt weiter gehen und deine Validierung machen.

6

Saturday, November 14th 2009, 7:03pm

Du meinst also "$eventObj->useCaptcha = false" nicht nur setzen, wenn "$eventObj->useCaptcha" gesetzt ist (so wie oben), sondern Grundsätzlich?

// Edit:

PHP Quellcode

1
2
3
4
5
6
7
8
9
if ($this->useCaptcha == null) {
  	  if (isset($eventObj->useCaptcha)) {
		  $this->useCaptcha = $eventObj->useCaptcha;
  	  } else {
		  $this->useCaptcha = true;
  	  }
	  }
 
	  $eventObj->useCaptcha = false;


Ohne Erfolg

This post has been edited 1 times, last edit by "Gnex" (Nov 14th 2009, 7:09pm)


7

Sunday, November 15th 2009, 6:38pm

"ohne erfolg" was meinst du damit?

du sollst ja wie gesagt in mehreren schritten vorgehen um was wcf captcha erstmal zu deaktivieren und anschließend dein captcha einzufügen.
Auch gut zu wissen wäre zu welchem Zeitpunkt du useCaptcha überschreibst.

8

Sunday, November 15th 2009, 8:11pm

Hi,

"ohne erfolg" ist die Änderung (s. oben) verlaufen; sprich: Es ist noch immer die selbe Problematik.
Ich überschreibe useCaptcha vom WCF nach meiner IF-Abfrage (s. oben).

9

Monday, November 16th 2009, 8:55am

aber zu welchem Zeitpunkt? Welcher Event? Die Reihenfolge ist entscheidend.

10

Friday, December 11th 2009, 4:17pm

Sorry, dass ich mich erst jetzt wieder melde. Der EL ist auf folgende Klasse mit den dazugehörigen Events festgelegt:

- CaptchaForm::validate
- RegisterForm::assignVariables
- RegisterForm::readData
- RegisterForm::validate
- UserLoginForm::assignVariables
- UserLoginForm::readData
- UserLoginForm::validate

11

Sunday, December 13th 2009, 5:16pm

Ich habs mal Implementiert. Du musst nur noch die Recaptcha Methode implementieren.

PHP Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public function execute($eventObj, $className, $eventName) {
	// break
	if(!isset($eventObj->useCaptcha) || !$eventObj->useCaptcha) {
		return;
	}
 
	// completely disable parent handler
	$eventObj->useCaptcha = false;
 
	// bind
	$this->eventObj = $eventObj;
 
	// call our handler, if method is implemented
	if(method_exists($this, $eventName)) {
		$this->$eventName();
	}
}
 
public function readData() {
	$this->eventObj->captchaID = Recaptcha::create();
}
 
public function validate() {
	$this->eventObj->captcha = new Recaptcha($this->eventObj->captchaID);
	$this->eventObj->captcha->validate($this->eventObj->captchaString);
}

12

Sunday, December 13th 2009, 6:22pm

Ich habs folgendermaßen abgeändert:

PHP Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
public function execute($eventObj, $className, $eventName) {
	  #WCF::getSession()->unregister('captchaDone');
 
	// break
	if(($className != 'RegisterForm' && $className != 'UserLoginForm') && (!isset($eventObj->useCaptcha) || !$eventObj->useCaptcha)) {
  	return;
	}
 
	// completely disable parent handler
	$eventObj->useCaptcha = false;
 
	// bind
	$this->eventObj = $eventObj;
 
	// call our handler, if method is implemented
	if(method_exists($this, $eventName)) {
  	$this->$eventName();
	}
  }
 
  public function validate() {
	if(!WCF::getSession()->getVar('captchaDone')) {
  	$this->resp = recaptcha_check_answer($this->privateKey, $_SERVER["REMOTE_ADDR"], $_REQUEST["recaptcha_challenge_field"], $_REQUEST["recaptcha_response_field"]);
  	if($this->resp->is_valid) {
  		WCF::getSession()->register('captchaDone', true);
  		$this->eventObj->captcha->delete();
  	} else {
    	$this->error = $this->resp->error;
  	}
	}
  }
 
  public function validateCaptcha() {
	if(!WCF::getSession()->getVar('captchaDone')) {
  	$this->resp = recaptcha_check_answer($this->privateKey, $_SERVER["REMOTE_ADDR"], $_REQUEST["recaptcha_challenge_field"], $_REQUEST["recaptcha_response_field"]);
  	if($this->resp->is_valid) {
  		WCF::getSession()->register('captchaDone', true);
  		$this->eventObj->captcha->delete();
  	} else {
    	$this->error = $this->resp->error;
  	}
	}
  }
 
  public function assignVariables() {
	if(!WCF::getSession()->getVar('captchaDone')) {
  	WCF::getTPL()->assign('captcha', recaptcha_get_html($this->publicKey, $this->error));
	}
  }



Leider der selbe Fehler - Es wird ein Error ausgegeben, obwohl es keinen Grund dazu gibt.

13

Sunday, December 13th 2009, 8:02pm

Nimm meinen Code mal ohne Anpassung. Du versuchst wieder 10 Schritte auf einmal zu machen.
Das macht es für mich nur schwierig den Fehler zu finden.

Schritt 1: Sorge dafür, dass trotz falschem Captcha kein Fehler geworfen wird.
Schritt 2: Sorge dafür, dass das recaptcha angezeigt wird.
Schritt 3: Validiere das recaptcha

Wege zum Erfolg:
Also du musst schonmal nur die CaptchaForm Events nutzen.
Davon aber zumindestens readData und validate.

14

Tuesday, December 22nd 2009, 3:45pm

Leider bringt mich das zu gar keinem Ziel.

// Edit: Mittlerweile bin ich beim prüfen angekommen und erhalten auf einmal den Fehler "To use reCAPTCHA you must get an API key from http://recaptcha.net/api/getkey", obwohl einer vorhanden und dieser auch richtig ist.

// Edit 2: Es liegt daran, dass die captchaID mit "intval" behandelt wird, ich brauche aber einen String.

This post has been edited 2 times, last edit by "Gnex" (Dec 22nd 2009, 5:37pm)


15

Tuesday, December 22nd 2009, 9:03pm

Erledigt; Wer sich dafür Interessiert, kann sich gerne Melden. Ich werds allerdings nicht hochladen, da es keine Administration dazu gibt.

Similar threads

Social bookmarks