WCF-EventListener - reCAPTCHA

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • WCF-EventListener - reCAPTCHA

    Hallo,

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

    Quellcode

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



    Das reCAPTCHA wird auch richtig angezeigt. Wenn dies aber als richtig anerkannt wurde, wird das WCF Captcha nochmal angezeigt.
  • 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.
  • 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.
  • 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.
  • Du meinst also "$eventObj->useCaptcha = false" nicht nur setzen, wenn "$eventObj->useCaptcha" gesetzt ist (so wie oben), sondern Grundsätzlich?

    // Edit:

    Quellcode

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


    Ohne Erfolg

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von Gnex ()

  • 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
  • Ich habs mal Implementiert. Du musst nur noch die Recaptcha Methode implementieren.

    Quellcode

    1. public function execute($eventObj, $className, $eventName) {
    2. // break
    3. if(!isset($eventObj->useCaptcha) || !$eventObj->useCaptcha) {
    4. return;
    5. }
    6. // completely disable parent handler
    7. $eventObj->useCaptcha = false;
    8. // bind
    9. $this->eventObj = $eventObj;
    10. // call our handler, if method is implemented
    11. if(method_exists($this, $eventName)) {
    12. $this->$eventName();
    13. }
    14. }
    15. public function readData() {
    16. $this->eventObj->captchaID = Recaptcha::create();
    17. }
    18. public function validate() {
    19. $this->eventObj->captcha = new Recaptcha($this->eventObj->captchaID);
    20. $this->eventObj->captcha->validate($this->eventObj->captchaString);
    21. }
    Alles anzeigen
  • Ich habs folgendermaßen abgeändert:

    Quellcode

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



    Leider der selbe Fehler - Es wird ein Error ausgegeben, obwohl es keinen Grund dazu gibt.
  • 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.
  • 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 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.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von Gnex ()