PDO Loginscript mit automatisch gesendeter Mail, macht probleme

  • Hallo,
    jetzt habe ich mich soweit in POD eingelesen, dass ich ein funktionierendes Registrierungsskript hinbekommen habe.
    Das ganze läuft so ab, dass der User beim registrieren, seine Daten eingibt und diese dann in eine Datenbank geschrieben werden.
    Zusätzlich gibt es dann noch die Spalte aktivierungscode.
    Der aktivierungscode wird erzeugt, indem eine Zufallszahl mit md5 gehasht wird.
    DIeser Code soll dann per Mail an die angegebene Mailadresse gesendet werden und zusätzlich in die DB eingetragen werden.
    Das senden per Mail klappt, in die DB wird aber nichts eingetragen... Da steht immer noch 0.
    Hier der entsprechende Codeausschnitt:


    Außerdem landet die Mail bei gmail automatisch im Spamordner, weil die Nachricht große ähnlichkeit mit anderen Spamnachrichten aufweist.
    Das ist an sich ja auch klar.
    Es gibt eine automatisch erzeugte Mail, mit einem erzeugten Link von einer Mailadresse die es gar nicht gibt.
    Aber wie kann ich das verhindern? Solche Mails werden ja eigentlich überall versendet, wo man sich registriert.
    Wie machen andere das?


    Gruß
    Torben

  • Hey,


    wenn die anderen Daten korrekt eingetragen werden, kann es ja tehoretisch nur am Typ des Feldes liegen, wo die Daten eingetragen werden sollen. Um was für ein Feld handelt es sich bei aktivierungscode? MD5 strings haben eine Länge von 32 Byte oder 16 Byte mit raw_output [md5($rand, true);] und sind vom Typ char.


    Dass deine Mails im Spam Ordner landen, liegt an der Konfiguration des sendenden Servers. Da im Weg sind meistens verschiedene DNS Settings oder das Sender Policy Framework. In der Regel kannst du da nicht viel gegen unternehmen, außer du hast Zugriff auf die Konfiguration des Mailservers. Das sollte aber nur der Fall sein, wenn du selber Host bist.


    Deine header stimmen soweit. Da kann aber auch ein Problem mit dem Absender auftreten. Wenn dein Hoster die Mails über eine IP verschickt, die nicht mit der im Absender und Reply-To angegebenen Domain verknüpft ist, schlagen die empfangenden Server in der Regel schon Alarm. Außerdem solltest du bei Mails auf die keine Antwort erfolgen soll als "Reply-To" Header immer "noreply@esmurf.de" oder "no-reply@esmurf.de" setzen. Der empfangende Server interpretiert das in der Regel gesondert.


    Wenn du mal ganz viel Langeweile hast, findest du hier alles was du über das Senden von Mails wissen musst.

  • Du verwendest (was ich Deinem Code entnehme) bei der Aktivierung sicherlich eine Query wie

    SQL
    select * from users where aktivierungscode = :aktivierungscode


    denn du nutzt keine userid im Link - was nicht schlimm ist.
    Es könnte mit rand() aber vorkommen, dass 2 order mehr User den gleichen Aktivierungscode besitzen/bekommen.
    Dadurch kann User A evtl User X aktivieren.
    Vorschlag: siehe code


    Evtl auch die Fehler beim prepare und execute abfangen, damit Du weißt, was nicht geht, wenn was nicht geht.
    + htmlspecialchars im Emailtext und den Link als Link (a tag) einbauen.



    Ansonsten wäre es interessant, was (wie Basi schon sagte) das Feld aktivierungscode für ein Type ist.

  • Es könnte mit rand() aber vorkommen, dass 2 order mehr User den gleichen Aktivierungscode besitzen/bekommen.
    Dadurch kann User A evtl User X aktivieren.


    Stimmt, daran habe ich gar nicht gedacht. Habe ich nun korrigiert. Danke für den Tipp.
    Ich hatte das Feld als Int definiert... Habe es jetzt aber auf char korregiert


    Edit:
    Ich bin immer noch dabei, mich durch das Aktivierungscode-Skript zu beißen.
    Und zwar möchte ich das ganze doch mit einer ID umsetzen.
    Ich wollte bewusst keinen fertigen Code nehmen, weil ich die ganze PDO-Thematik endlich komplett verstehen will.
    Dafür habe ich jetzt die Erstellung des Aktivierungscodes in eine andere Funktion ausgelagert.
    Jetzt wollte ich dafür die ID aus der Datenbank auslesen...

    PHP
    $aktivierungscode = random_string();
    $statement = $pdo->prepare("INSERT INTO users (username, email, passwort, aktivierungscode) VALUES (:username, :email, :passwort, :aktivierungscode)");
    $result = $statement->execute(array('username' => $username, 'email' => $email, 'passwort' => $passwort_hash, 'aktivierungscode' => $aktivierungscode));
    $query = "SELECT id FROM users WHERE username = $username";
    $userid = $pdo->query($query);


    ... und dann an den Link anfügen:

    PHP
    $link = 'http://194.95.47.100/toro4621/aktivieren.php?userid='.$userid.'&code='.$aktivierungscode;


    Das klappt aber nicht. Warum? Was habe ich falsch gemacht?



    Gruß
    Torben
    var_dump($userid); gibt mir übrigens bool(false) aus... aber das hilft mir leider auch nicht weiter

  • Fehler abfangen. (Siehe meinem Post weiter oben)


    Hat denn die inset-Query funktioniert?
    Die ->query hat jedenfalls nicht funktioniert -
    siehe: http://php.net/manual/de/pdo.query.php "PDO::query() returns a PDOStatement object, or FALSE on failure."
    Also ->query returnt false, wenn ein Fehler aufgetreten ist.
    ... deshalb - Fehler abfangen ... immer :)


    Tipp: http://php.net/manual/de/pdo.lastinsertid.php

    PHP
    $aktivierungscode = random_string(); 
    $statement = $pdo->prepare("INSERT INTO users (username, email, passwort, aktivierungscode) VALUES (:username, :email, :passwort, :aktivierungscode)");
    // error abfangen
    $result = $statement->execute(array('username' => $username, 'email' => $email, 'passwort' => $passwort_hash, 'aktivierungscode' => $aktivierungscode));
    // error abfangen
    
    
    
    
    $userid = $pdo->lastInsertId();


    Du musst aber keine user id anhängen - wie schon gesagt - ein guter Aktivierungscode (db Feld UNIQUE) tut es auch.
    Nur ein Hinweis. Wenn Du das so machen willst, dann werde ich Dich nicht davon abhalten :) (ist also nicht falsch)



    BTW: was wird für den Login genutzt? Username oder Email? Oder ist beides möglich?
    Ich frage, weil diese(s) Feld(er) dann UNIQUE sein sollten.


    Wenn also Username und Passwort -Login:

    SQL
    UNIQUE INDEX `idx_mein_index_name` (`username` ASC)


    Wenn Username order Email und Passwort -Login:

    SQL
    UNIQUE INDEX `idx_mein_index_name` (`username` ASC, `email` ASC) -- die combi username und email darf nur einmal vorkommen
  • Das eintragen in die DB mit dem insert-Query hat ohne Probleme funktioniert.
    Das problem liegt bzw lag bei meinem select-Query.
    Wenn ich in bei diesem Query den Fehler abfange:

    PHP
    $query = "SELECT id FROM users WHERE username = $username";
    						$userid = $pdo->query($query);
    						if (!$userid) {
    							echo "\nPDOStatement::errorInfo():\n";
        						print_r($userid->errorInfo());
    						}


    bekomme ich die Fehermeldung: PDOStatement::errorInfo(): Fatal error: Call to a member function errorInfo() on a non-object in /home/stud/t/toro4621/public_html/registrieren.php on line 104


    Zeile 104 ist print_r($userid->errorInfo());
    Daraus schließe ich, dass $userid keinen Wert hat, weil der Befehl $userid = $pdo->query($query); so nicht funktioniert....
    $userid = $pdo->lastInsertId(); ist atürlich der elegantere Weg, welcher Funktioniert uund welchen ich auch nutzen werde.
    Aber für die Zukunft würde ich trotzdem gerne wissen, ob ich Datenbankeinträge mit dem oberen Befehl so auslesen kann, bzw was ich dabei falsch gemacht habe.

  • Fehler beim Fehler abfangen :D

    PHP
    $query = "SELECT id FROM users WHERE username = $username";
                            $userid = $pdo->query($query);
                            if (!$userid) { // wenn userid "NICHT" ist (als hier im Bsp false)
                                echo "\nPDOStatement::errorInfo():\n";
                                // falsch =) print_r($userid->errorInfo());
    print_r($pdo->errorInfo()); // $pdo ist das obeject, das "etwas tun sollte". $pdo->query funktionierte nicht, daher fragen wir $pdo, was denn schief gelaufen ist
                            }
  • Zitat

    PDOStatement::errorInfo(): Array ( [0] => 42S22 [1] => 1054 [2] => Unknown column 'eingegebener Username' in 'where clause' )


    Das ist die Fehlermeldung die dabei raus kommt.
    Für die ersten Codes konnte ich keine Bedeutung finden. Aber aus dem dritten Teil kann ich entnehmen, dass irgendwas mit der where Anweisung nicht stimmt.
    Der Spaltenname in der Tabelle heißt aber username und die Variable $username hat auch den eingegebenen Usernamenwert... ?

  • Du hast irgendwo eine Query mit "eingegebener Username" als Feldnamen abgeschickt.
    Den Teil des Codes hast Du wohl aber nicht hier gepostet.


    Such mal im Code nach "eingegebener Username" -- irgendwo muss das ja in eienr SQL-Anweisung stehen (oder in einer Variable die dann in einer Query genutzt wird).

  • "eingegebener Username" ist das Was beim Registrierungsformular im Inputfeld mit dem Namen "username" als Nutzername eingegeben wird.
    Dieser name wird dann in der DB in der Tabelle users in die Spalte "username" geschrieben.
    Außerdem ist er in der Variable $username gespeichert.


    Schließlich wird diese in de Queryanweisung

    PHP
    $query = "SELECT id FROM users WHERE username = $username";

    verwendet.


    Also muss an dieser Anweisung etwas falsch sein, was ich aber nicht verstehe :S

Jetzt mitmachen!

Sie haben noch kein Benutzerkonto auf unserer Seite? Registrieren Sie sich kostenlos und nehmen Sie an unserer Community teil!