Passwort vergessen via E-Mail [MySQL]

Wichtiger Hinweis: Bitte ändert nicht manuell die Schriftfarbe auf schwarz sondern belasst es bei der Standardeinstellung. Somit tragt ihr dazu bei dass euer Text auch bei Verwendung unseren dunklen Forenstils noch lesbar ist!

Tipp: Ihr wollt längere Codeausschnitte oder Logfiles bereitstellen? Benutzt unseren eigenen PasteBin-Dienst Link
  • Moin,


    ich möchte dir nun gerne erklären, wie man eine Passwort vergessen Funktion via E-Mail macht.
    Ich zeige das hier an einem MySQL Beispiel. Damit meine ich, dass die Accounts mit MySQL gespeichert werden. Ich werde das Beispiel an der MySQL R5 Funktion zeigen.
    Du musst das an die Version die du benutzt anpassen. So dann beginne ich mal.


    Zuallererst muss man sich überlegen was man überhaupt alles braucht, damit man dieses System erstellen kann. Ich liste das mal auf.


    • Geduld
    • Anfänger Kenntnisse in PAWN
    • Das a_http Include
    • Das a_mysql Include deiner MySQL Version
    • OnPlayerCommandText
    • OnDialogResponse
    • E-Mail Adresse wurde gespeichert
    • PHP, da brauchst du keine Kenntnisse da ich das ja erkläre.


    Das alles brauchen wir, damit wir das System erstellen können. Begeben wir uns nun in das Script, dort sollte ja schon ein Login und Register System vorhanden sein. Wenn nicht, dann schau dir ein Tutorial dazu an, oder erstell es bevor du das hier machst. Beginnen wir nun mit der Vorbereitung für das Script. Wie oben schon geschrieben brauchst du das a_http Include. Falls du ein MD5 Include benutzt ist das gut, wenn nicht, auch nicht schlimm. Ich zeige die mir bekannten Hash Methoden, da ist bestimmt auch was für dich dabei. Beginnen wir nun mit dem Includieren von dem a_http Include.


    #include <a_http>


    Das Include ist schon im Includes Ordner von Pawno dabei. Das musst du also nicht extra downloaden. Hast du das Include nun eingebunden, machen wir mit den Dialogen weiter. Es müssen vier neue Dialoge dazu erstellt werden, einmal der Dialog für das Passwort Vergessen, dann einen für den Einstellungen Befehl (damit kann man dann später sein Passwort ändern), und zwei für das neue Passwort. Warum zwei, wird später klar. Machen wir das nun einmal. Ich zeige hier zwei Methoden, falls man eine der beiden benutzt.


    //Die anderen Dialoge
    #define DIALOG_PWV DialogID
    #define DIALOG_SETTINGS DialogID
    #define DIALOG_PWC DialogID
    #define DIALOG_PWC2 DialogID


    enum{
    //Die anderen Dialoge
    DIALOG_PWV,
    DIALOG_SETTINGS,
    DIALOG_PWC,
    DIALOG_PWC2
    }


    Soviel zu den Dialogen. Als nächstes musst du einen neuen callback (Public) erstellen. Dieser wird uns später darüber aufklären ob die E-Mail erfolgreich versendet wurde.


    forward EmailStatus(index, response_code, data[]);


    Den callback (Public) erstellst du dann ganz unten im Script, oder halt da wo er in keinem anderen callback (Public) ist.


    public EmailSenden(index, response_code, data[])
    {
    return 1;
    }


    Den füllen wir später mit Inhalt. Jetzt erstellen wir uns noch eine Playervariable, mit der wir dann steuern können, ab wann der Dialog kommt wo man die Passwort vergessen Funktion anwenden kann.


    new login_status[MAX_PLAYERS];


    So, jetzt hast du die Vorarbeit erledigt. Nun können wir uns nun der Arbeit zuwenden. Du gehst nun bei OnDialogResponse in den Login Dialog. Dort machst du dann, wenn das Passwort falsch eingegeben wurde, folgendes.


    switch(login_status[playerid])
    {
    case 0:
    {

    }
    case 1:
    {

    }
    case 2:
    {

    }
    case 3:
    {

    }
    }


    Was bewirkt dieser Code? Mit der Funktion switch lassen sich, abhängig vom Inhalt einer Variable, verschiedene Code Abschnitte ausführen. Die Funktion arbeitet also ähnlich wie mehrere if-Anweisungen. Als Beispiel würde das so aussehen.


    if(login_status[playerid] == 0) == case 0:
    if(login_status[playerid] == 1) == case 1:


    Das heißt dann also, dass ich dem Spieler drei Versuche lasse das Passwort richtig einzugeben. Das was jetzt folgt, kommt in die case 0, case 1 und case 2. Halt jeweils mit veränderter Versuchsanzahl.


    login_status[playerid]++;
    ShowPlayerDialog(playerid,Login,DIALOG_STYLE_PASSWORD,"Überschrift","Dein Passwort ist falsch. Versuch HIER DIE AKTUELLE ZAHL(bei case 0 währe das dann 1)/3","Anmelden","Abbrechen");


    Nun hat der Spieler drei Versuche das Passwort richtig einzugeben. Sollte der Spieler das Passwort dennoch falsch eingeben, kommt die case 3 ins Spiel. Denn dort sagen wir dem Spieler dann das er das Passwort zu oft Falsch eingegeben hat. Gleichzeitig geben wir ihm dann auch die Möglichkeit entweder einen Reconnect zu machen, um das nochmal zu versuchen, oder die Passwort vergessen Funktion anzuwenden. Das sieht dann wie folgt in der case 3 aus.


    ShowPlayerDialog(playerid, DIALOG_PWV, DIALOG_STYLE_MSGBOX, "Login","Du hast das Passwort zu oft Falsch eingegeben.\nMöchtest du es noch einmal versuchen? (Reconnect) Oder möchtest du die Passwort vergessen Funktion verweden?","Reconnect","PW Vergessen");


    Nun erstellen wir eine neue Abfrage in OnDialogResponse.


    if(dialogid == DIALOG_PWV)
    {


    }


    //oder falls du switch benutzt


    case DIALOG_PWV:
    {


    }


    Dort machen wir nun die Abfrage rein welcher Button betätigt wurde.


    if(response)//Wenn der linke Button gedrückt wurde (1)
    {


    }
    else//Wenn der rechte Button gedrückt wurde (0)
    {


    }


    Wenn nun der erste (linke) Button gedrückt wurde, soll der Spieler gekickt werden. Deswegen die Abfrage if(response).
    Wenn nun aber der zweite (rechte) Button gedrückt wurde, soll eine E-Mail versendet werden. Um eine E-Mail aus dem Gamemode heraus zu senden benutzten wir das a_http Include. Bevor ich das jetzt zeige, zeige ich zuerst die Funktion aus dem a_http Include womit man Daten an eine .php Datei übergeben kann.


    HTTP(index, type, url[], data[], callback[])


    Was das alle ist, zeige ich nun an dem Beispiel.


    new string[100],sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(string,sizeof(string), "domain.de/pw_reset.php?mail=%s&username=%s",GetString(playerid,"EMail"),sName);
    HTTP(playerid, HTTP_GET,string, " ", "EmailStatus");


    Was mache ich da jetzt genau? Ich erstelle zuerst einen string den ich später dann formatieren kann. Denn wir brauchen da ja 1. den Usernamen und 2. die E-Mail Adresse an die das geschickt werden soll. Dann erstelle ich sName, denn dann kann ich mit GetPlayerName den Namen des Spielers herausfinden. Als nächstes formatiere ich den String. Ich gebe die Domain und den Ort der .php Datei die wir noch erstellen werden. Ebenso gebe ich der .php Datei zwei Werte. Einmal die E-Mail Adresse und dann den Usernamen. GetString werde ich gleich zeigen, zuerst erkläre ich aber noch HTTP. So, beim HTTP angekommen legen wir gleich damit los den index zu bestimmen. Wir sagen, das der Index die ID bekommt, die der Spieler hat. Warum mache ich das bzw. warum ist das nötig? Das hat den einfachen Grund das die Anfragen unterscheidet werden müssen. Als nächstes bestimmen wir die Methode, mit der das ganze gesendet wird. Es gibt einmal die HTTP_GET und die HTTP_POST Methode. Hier benutzten wir aber die HTTP_GET Methode. Warum? Das ist leicht erklärt. Bei GET sieht man die Übergabe der Daten in der Adresszeile des Browsers. Jeder hat z.B. schon einmal eine Adresse wie diese gesehen: index.php?action=read&seite=1- hinter der aufzurufenden Datei (index.php) kommt das Fragezeichen und dahinter die Variablen die per GET übergeben werden. Verschiedene Variablen werden dann mit & voneinander getrennt. Als nächstes geben wir an, welche .php Datei ausgeführt werden soll. Also die URL zu der .php Datei die noch erstellt wird. Diese haben wir ja schon im format vorbereitet, das heißt man kann nun einfach string dort angeben. Als nächstes kommt ein leeres Feld. Warum fragst du dich jetzt? Das kann ich dir beantworten. Dieses Feld benötigt man wenn man mit der HTTP_POST Variante Daten übergeben will. Das ist hier aber nicht relevant da wir die HTTP_GET Methode verwenden. Das letzte Feld, wo EmailStatus steht ist der Callback (Public) der Aufgerufen werden soll. Dort kann man dann mit einer if Abfrage abfragen ob die E-Mail gesendet worden ist oder nicht.


    Jetzt zeige ich noch schnell die Funktion GetString, die ist dazu da um die E-Mail Adresse auszulesen. Wenn du selbst so eine Funktion hast, dann brauchst du diese Funktion nicht mehr in dein Script einfügen, du musst dann halt in dem Format das anpassen.


    stock GetString(playerid,name[])
    {
    new query[100],sName[MAX_PLAYER_NAME],value[50];
    GetPlayerName(playerid,sName,sizeof(sName));
    mysql_real_escape_string(sName,sName);
    format(query,sizeof(query),"SELECT `%s` FROM `accounts` WHERE `Name`='%s'",name,sName);
    mysql_query(query);
    mysql_store_result();
    mysql_fetch_row(value);
    mysql_free_result();
    return value;
    }


    So, alles was wir bisher in OnDialogResponse mache mussten ist nun fertig. Gehen wir nun in den Callback (Public) EmailStatus. Dort ist jetzt noch nichts drinnen, das ändern wir aber jetzt. Nun kommt folgende Abfrage rein.
    if(response_code == 200)
    {


    }
    else
    {


    }


    Was bedeutet jetzt die Zahl 200 und was ist response_code? Zuerst einmal zu der Zahl 200. Mit der Abfrage ob der response_code 200 ist, fragt man ab ob der request erfolgreich war. Also ob der Datenaustausch zwischen der .php Datei und dem Gamemode erfolgreich war. Die else Bedingung ist dafür da, wenn der Request nicht erfolgreich war. Machen wir erstmal das, wenn der Request erfolgreich war. Dort kommt jetzt wieder der normale Login Dialog, so wie du ihn beim Joinen hast rein. Ebenfalls geben wir eine Message aus, dass eine E-Mail versendet wurde.


    SendClientMessage(index,-1,"Es wurde nun ein neues Passwort an deine E-Mail Adresse geschickt");


    Der Spieler weiß jetzt das ein neues Passwort an seine E-Mail Adresse geschickt wurde. Jetzt kann er dann in sein E-Mail Postfach gehen, und dort sein neues Passwort herauskopieren und sich damit einloggen. Stop, nein das kann er nicht. Denn wir haben die .php Datei noch nicht erstellt. Das machen wir gleich, zuerst machen wir aber erst noch was passieren soll, wenn der Request nicht erfolgreich war. Das kommt in die else Bedingung rein.


    new string[50];
    format(string, sizeof(string), "Die E-Mail konnte nicht gesendet werden! Der Response Code lautet: %d", response_code);
    SendClientMessage(index, -1, string);
    SendClientMessage(index,-1,"Teile den Response Code einen Administrator mit");


    Ich lasse den Response Code ausgeben, damit, sofern der Code gemeldet wird, der Administrator oder Script weiß warum das nicht geht. Denn es gibt 6 verschiedene Codes in dem a_http Include


    HTTP_ERROR_BAD_HOST 1
    HTTP_ERROR_NO_SOCKET 2
    HTTP_ERROR_CANT_CONNECT 3
    HTTP_ERROR_CANT_WRITE 4
    HTTP_ERROR_CONTENT_TOO_BIG 5
    HTTP_ERROR_MALFORMED_RESPONSE 6


    Der Scriptteil ist nun fertig, bzw. fast fertig. Es kommt später noch etwas. Jetzt erstellen wir eine .php Datei mit dem Namen pw_reset.php. Denn diesen Namen habe ich beim format vor dem HTTP angegeben. Jetzt geht es in den PHP Teil. Wenn du keine Ahnung von PHP hast, dann ließ dir das genau durch, soll jetzt nicht heißen das wenn du PHP kannst du das einfach rauskopieren kannst. In PHP ist es generell so das man mit <?php ?> einen PHP Bereich erstellt. Alles was in diesen zwei Teilen steht wird als PHP Code gewertet. Man kann <?php ?> machen oder <? ?> kommt auf das selbe hinaus. So, in der pw_reset.php erstellen wir nun so einen Bereich.


    PHP
    <?
    
    
    ?>


    Was genau müssen wir jetzt machen, damit die E-Mail gesendet wird, und 2. das Passwort in der Datenbank erneuert wird. Zuerst muss ich sagen das PHP PAWN ähnlich ist. Was meine ich damit? Ich meine folgendes. In PHP gibt es auch if Abfragen, es gibt die verschiedenen Operatoren usw.. Aber es gibt eben auch andere Funktionen. Ich denke aber, man findet sich in PHP schnell zurecht wenn man PAWN einigermaßen beherrscht. Beginen wir nun mit der ersten Abfrage, und zwar ob in "mail" und "username" etwas vorhanden ist. Also wenn z. B. das so ist: pw_reset.php?mail=email&username=name
    Sollte mail oder username leer sein, dann soll ja nichts passieren, denn wir brauchen beide Daten damit das System klappt. In PHP macht man das mit isset.


    PHP
    if(isset($_GET['mail']) && isset($_GET['username']))
    {
    
    
    }


    Was mache ich jetzt dort? Ich frage erstmal mit der if Abfrage ab, ob mail und username einen Wert hat. Das mache ich mit isset in der if Abfrage. Nun benutze ich $_GET. Warum? Nun ich übergebe die Daten ja mit der HTTP_GET Methode im Gamemode, deswegen muss ich hier auch $_GET anwenden. Denn damit hol ich mir dann den Wert der in mail oder username steht. Wenn ich die HTTP_POST Methode genommen hätte, müsste ich dort dann $_POST anwenden. Die Abfrage steht, kümmern wir uns nun um den Rest.
    Bevor ich nun weiter fortfahre merke ich noch etwas an. Wenn wir das System jetzt so schreiben würden, dass das Passwort geändert wird wenn der User auf dem Server die Passwort vergessen Funktion anwendet, könnte da sich ein X-beliebiger Spieler mit dem Namen eines anderen Spielers Joinen, und dauernd das Passwort ändern. (Danke für den Hinweis xyShadowyx: ). Damit so etwas nicht passieren kann bauen wir jetzt noch eine Sicherheitsmaßnahme ein. Wie sieht die aus? Ich werde insgesamt zwei E-Mails an den Spieler senden lassen. Die erste E-Mail wird einen Link enthalten, mit dem sich der User dann verifizieren kann. Wenn sich der User dann verifiziert hat, lasse ich eine zweite E-Mail senden, worin dann das Passwort steht und gleichzeitig in der Datenbank das alte durch das neue Passwort ersetzt wird. Wir erstellen also jetzt eine zweite Abfrage mit isset. Diese Abfrage kommt in die erste Abfrage rein.


    PHP
    if(isset($_GET['status']))
    {
    
    
    }
    else
    {
    
    
    }


    Warum ich status Abfrage sieht man dann gleich. Zuerst mache ich aber das was in die else Bedingung kommt, also die erste E-Mail mit dem Bestätigungslink.
    Ich muss mir jetzt also überlegen welche Werte ich brauche, bzw. welche Variablen gesetzt werden müssen damit das System klappt. Ich sage hier, da die Abfrage in der ersten Abfrage ist, dass ich nochmal alle Werte haben will. Den Usernamen, die E-Mail und dann den Status.
    Bereiten wir jetzt erstmal den Inhalt der E-Mail Adresse vor. Wir benötigen dazu die Funktion mail. Schauen wir uns erstmal die Funktion mail an.


    PHP
    bool mail ( string $to , string $subject , string $message [, string $additional_headers [, string $additional_parameters ]] )


    Die Funktion hat drei Parameter. Ich erkläre nun alle hintereinander.


    $to
    Dem $to Parameter sagt man an welche E-Mail Adresse oder Adressen die E-Mail gesendet werden soll.
    $subject
    Mit dem $subject Parameter legt man den Titel der E-Mail Adresse fest.
    $message
    Bei dem $message Parameter gibt man den Inhalt der E-Mail an.
    $additional_headers (Optional)
    Das ist ein String, der am Ende des E-Mails Headers eingefügt werden soll.
    $additional_parameters (Optional)
    Der additional_parameters-Parameter kann benutzt werden, um zusätzliche Parameter an das Programm zu senden, das für den E-Mail-Versand konfiguriert ist.


    Die Header Parameter können z. B. sein, von wem die E-Mail gesendet wurde, an welche E-Mail Adresse das zurückgeschickt werden soll (wenn man Antworten will) usw. Schau dir die Funktion auf php.net an um weiteres zu erfahren. Das machen wir jetzt mal, damit du auch siehst wie das Funktioniert. Zuerst fertigen wir die Message an, und danach dann die Header Daten. Ich verwende hier, zur Übersicht, .= verwenden. Was das bedeutet erkläre ich etwas weiter unten. Das was jetzt folgt kommt in die else Bedingung bei der Status Abfrage.


    PHP
    $username = $_GET['username'];
    $email = $_GET['mail'];
    $message = "Hallo $username<br /><br />";
    $message .= "Dies ist eine Automatisch Generierte E-Mail in der du einen Bestätigungslink für deine Passwort Anfrage erhälst.<br />";
    $message .= "Klicke den Link NUR an wenn du diese E-Mail auch angefordert hast.<br /><br />";
    $message .= "Andernfalls wird dein Passwort von dem SAMP Server überschrieben mit einem neuen.";
    $message .= "Link: <a href="http://domain.php?pw_reset.php?mail='.$email.'&username='.$username.'&status=resetcomplete"><b>http://domain.php?pw_reset.php?mail='.$email.'&username='.$username.'&status=resetcomplete</b></a>";


    Was mache ich jetzt in diesem Teil?
    Ich lege zuerst den Wert von $_GET['username'] und $_GET['mail'] auf zwei dazu erstellte Strings. Das macht es mir später im Link einfacher. Als nächstes erstelle ich die Message, also den Inhalt der dann in der E-Mail stehen wird. Dann, in der letzen Zeile von Message gebe ich einen Link an, den der Spieler anklicken muss damit das Passwort erneuert wird. Einen Link erstellt man mit <a href="pfad">Wort</a>. Ist kein PHP sondern HTML. Wird können das hier trotzdem anwenden da das später in der E-Mail in HTML angezeigt wird. Jetzt haben wir eine Link der andere User daran hindert aus Spaß das Passwort von Usern zu ändern. Machen wir dann mal gleich weiter mit dem Rest der E-Mail. Machen wir nun den Header, denn wenn man jetzt die E-Mail senden würde, dann würden die ü ä ö komisch angezeigt werden, ebenfalls würde <br /> angezeigt werden und es würde kein Zeilenumbruch geschehen. (<br /> ist der Zeilenumbruch in HTML). Um das jetzt zu ändern müssen wir erstmal den Content-Type html angeben, und den charset auf utf-8 stellen. Ebenfalls will ich die Absender E-Mail dort angeben sowie die E-Mail Adresse zum Antworten.


    PHP
    $header = 'From: SAMP - Server <info@domain.de>' . "\r\n";
    $header .= 'Reply-To: info@domain.de' . "\r\n";
    $header .= 'Content-Type: text/html charset="utf-8"\n';


    Was mache ich jetzt? Ich Gebe mit From an von wem die E-Mail kommt. Dazu gebe ich den Namen und die E-Mail Adresse an.
    Mit Reply-To gebe ich an an welche E-Mail Adresse das gesendet wird wenn der User auf die E-Mail antwortet.
    Content-Type und charset sollten klar sein. Jetzt haben wir die Vorbereitung abgeschlossen, und nun können wir die E-Mail mit der Funktion mail ab.


    PHP
    mail($email,"Passwort vergessen Funktion",$message,$header);


    Die E-Mail mit dem Link wurde also jetzt gesendet. Machen wir nun mit dem Passwort weiter.
    Ich will ein Passwort haben, das Random erstellt wird. Dazu schauen wir uns jetzt erstmal die Random Funktion in PHP an, dort heißt sie rand.


    PHP
    int rand ( int $min , int $max )


    Wir haben dort zwei Parameter, einmal $min und einmal $max. Das bedeutet einfach nur die Minimal und Maximal Angabe. Wir verwendet man jetzt diese Funktion? Ich zeige das mal an einem Beispiel.


    PHP
    $zufall = rand(1,50);


    Mittels rand wird nun eine ganzzahlige (17, 28 usw.) Zufallszahl aus dem Zahlenpool von 1 bis 50 ausgewählt. Das Problem ist jetzt nur, dass das nur Zahlen sind. Ich will aber ein Passwort aus Buchstaben und Zahlen. Und das soll auch etwas länger sein, 20 Zeichen würde ich jetzt mal sagen. Wie bekomme ich das jetzt hin? Nur alleine mit rand? Nein damit bekomme ich das nicht hin. Ich muss mir also eine Funktion erstellen womit ich 1. die Länge bestimmen kann und 2. bestimmen kann das Zahlen und Buchstaben darin vorkommen. Dazu jetzt einfach in die if Abfrage folgendes rein machen.


    PHP
    function GeneratePasswort($laenge)
    {
    
    }


    Ich erstelle nun eine neue Funktion, mit dazu sage ich schon einmal das der erste und letzte Parameter in dieser Funktion die Länge sein soll. Anwenden würde man diese Funktion dann so.


    PHP
    $passwort = GeneratePasswort(länge);


    Bei der Länge würde ich jetzt 20 eingeben, da ich ein Passwort haben will das aus 20 Zeichen besteht. Um das jetzt hinzubekommen, das man so ein Langes Passwort mit Buchstaben und Zahlen bekommt, müssen wir jetzt einiges machen. Zuerst einmal bestimmen wir welche Zahlen und Buchstaben in dem Passwort vorkommen sollen.


    $random_zeichen = "0123456789abcdefghijklmnopqrstuvwxyz";


    Ich will das die Zahlen 0 - 9 und die Buchstaben von klein a - z darin vorkommen. Als nächstes müssen wir eine Schleife machen, die genau so lange läuft wie ich es Angebe, also die Länge. Dazu machen wir jetzt folgendes.


    PHP
    for ($a = 0; $a <= $laenge; $a++) 
    { 
    	$b = rand(0, strlen($random_zeichen ) - 1); 
    	$rndstring .= $random_zeichen [$b]; 
    }


    Was mache ich da jetzt? Ich Erstelle genauso wie in PAWN eine for Schleife die genau so lange läuft wie ich das Angebe mit der Länge. Als nächstes lege ich das Random Ergebnis das ich mit rand erzeuge auf die Variable $b. In der Random Funktion gebe ich dann an, dass 0 der Minimale Wert ist, und das Ergebnis von strlen($random_zeichen) -1 das Maximal Ergebnis ist. Strlen ist in PHP genau das selbe wie in PAWN. Wurde das dann gemacht, sage ich das der String $rndstring das neue Zeichen hinzugefügt werden soll. Denn mit .= sagt man, dass das was dahinter Folgt hinzugefügt werden soll. Um das besser zu verstehen mache ich mal ein Beispiel.


    PHP
    $wort = "Hallo";
    $wort .= "Welt";


    Wenn man das nun ausgeben würde, würde dort dann "Hallo Welt" stehen. So einfach ist das, und deswegen fahren wir auch gleich fort.
    Wir bekommen nun in den String $rdnstring die zwanzig zufälligen Zeichen. Jetzt müssen wir das noch zurückgeben, damit die Funktion dann auch angewendet werden kann. Das macht man mit return.


    PHP
    return $rndstring;


    Die Funktion ist nun fertig, und man kann sie nun anwenden. Nun kommt unter die Funktion folgendes.


    $passwort = GeneratePasswort(20);
    $username = $_GET['username'];
    $email = $_GET['mail'];


    Was mache ich da jetzt? Ich lege zuerst ein zwanzig Zeichen langes Passwort in den String $passwort. Als nächstes übergebe ich die Werte von "username" und "mail" in die zwei erstellten strings. Wenn man jetzt $passwort, $username und $mail ausgeben würde, würde man dort die Werte haben die in der Browserzeile dann stehen. Also bis auf das Passwort, das wird ja in der .php Datei neu erstellt. Haben wir das gemacht, Hashen wir das Passwort nun. In PHP kann man das entweder, falls man MD5 verwendet, direkt mit


    PHP
    md5(passwort)


    machen, oder man verwendet die Funktion hash. Kommt aufs selbe wenn man md5 benutzt. Man hat aber andere Hash Methoden zur benutzen wenn man die Funktion hash verwendet. Aber wie benutzt man die? Ich zeige erstmal wie die aufgebaut ist.


    PHP
    string hash ( string $algo , string $data [, bool $raw_output = false ] )


    Die Funktion hat zwei Parameter, einmal die Methode (MD2, MD4, MD5, SHA1 usw...), und dann das, was man Gehasht haben möchte. Also in diesem Fall währe das dass Passwort.
    Anwenden würde man das dann so


    hash('md5','Passwort');


    Wenn man das dann ausgeben würde, würde das den MD5 Hash von "Passwort" ausgeben. ABER in Kleinbuchstaben. Das Include für PAWN macht das in Großbuchstaben. Also müssen wir jetzt den String irgendwie auf Großbuchstaben bekommen. Das macht man mit der Funktion strtoupper. Die Übersicht über die ganzen Methoden findest du hier (http://php.net/manual/de/function.hash.php#104987). So, soweit so gut, jetzt wissen wir wie man das Passwort Hasht. Ich zeige das hier an den zwei Beispielen MD5 und Whirlpool, da es das ja auch für PAWN gibt.


    PHP
    $hash_md5 = strtoupper(hash('md5',$passwort));
    $hash_wh = strtoupper(hash('whirlpool',$passwort));


    So, jetzt haben wir die zwei Hashs, je nachdem welchen Hash du nimmst kannst du das andere weg lassen.
    Wir haben nun alle nötigen Informationen vorhanden um eine erneute E-Mail zu verschicken. Und zwar die E-Mail wo das Passwort drinnen steht. Ich habe Bewusst die Hashs auf neue String gelegt, da ich dem Spieler ja nicht das Gehashte Passwort zeigen will. Sonst kann der sich ja nicht einloggen. Beginnen wir nun wieder damit den Inhalt der E-Mail vorzubereiten. Hierbei braucht man nun nur eine Zeile da es ja nicht viel zu schreiben gibt. Ebenfalls können wir gleich die Header Daten mit dazu angeben.


    PHP
    $message = "Dein neues Passwort: <b>$passwort</b>";
    $header = 'From: SAMP - Server <info@domain.de>' . "\r\n";
    $header .= 'Reply-To: info@domain.de' . "\r\n";
    $header .= 'Content-Type: text/html charset="utf-8"\n';";


    Es ist nun alles fertig, und wir können die E-Mail nun absenden.


    PHP
    mail($email,"Passwort vergessen Funktion",$message,$header);


    Jetzt haben wir dem Spieler sein neues Passwort zugeschickt. Das Problem ist jetzt nur, wie bekommen wir das jetzt in die Datenbank rein bzw. wie ersetzen wir das alte durch das neue Passwort?
    Das machen wir mit dem MySQL Befehl UPDATE. Aber bevor wir den benutzten können, müssen wir erstmal eine Verbindung zur Datenbank aufbauen. Das macht man mit mysql_connect. Steht dann die Verbindung muss man noch die Datenbank auswählen, in der die Accounts liegen. Das macht man mit mysql_select_db. Wenden wir das jetzt mal an.


    PHP
    $verbindung = mysql_connect("Host","Username","Passwort");
    mysql_select_db("DBName");


    So, wir haben jetzt eine Verbindung zur Datenbank, und die Datenbank ausgewählt. Wir sehen die .php Datei ja selber nicht, das wird ja vom Gamemode ausgeführt. Aber normalerweise, wenn man die .php Datei sieht, würde man eine Meldung reinmachen, wenn die Verbindung nicht erfolgreich war. Das zeige ich hier nicht, da das jetzt nicht relevant ist. Jetzt müssen wir einen MySQL Befehl bzw. den UPDATE Befehl ausführen. Das macht man, wie in PAWN mit dem R5, mit mysql_query Hier ist es jetzt so, das wir den MySQL Befehl nicht zuerst formatieren müssen, das ist ja in einer MySQL Version glaub ich auch so, da heißt das dann mysql_tquery oder so, weiß ich jetzt nicht genau. Hier machen wir den Befehl, wenn wir keine festen Werte benutzten so.


    PHP
    $query = mysql_query("UPDATE `accounts` SET `Passwort`='$hash_daswasduhast' WHERE `Name`='$username'");


    Jetzt wird glaube ich auch klar, warum ich den Namen mit übergeben habe. So, der Query sollte jetzt ausgeführt werden. Wenn der Query aber aus irgendeinem Grund nicht ausgeführt werden sollte, kann man eine Abfrage einbauen die dann sagt, was falsch ist bzw. ob der Query überhaupt ausgeführt wurde. Da wir aber nicht die .php Datei betrachten, können wir uns das sparen. Ich zeige aber trotzdem mal, falls du was anderes machen willst, wie man das abfragt und auswertet ob der Query ausgeführt wurde. mysql_query gibt, wenn der Query erfolgreich war, true zurück. Wenn der Query nicht ausführbar war, false. Deswegen kann ich jetzt einfach folgende abfrage machen.


    if($query)
    {


    }
    else die("Es gab einen Fehler".mysql_error());


    Was mache ich da jetzt? Ich frage mit if($query) ob mysql_query den Wert True zurück gegeben hat. Sollte das der Fall sein, senden wir die E-Mail mit dem Passwort an die E-Mail von dem Spieler. Das sehen wir uns gleich an. Wenn jetzt aber False ausgegeben wurde, wird die else Bedingung ausgeführt. Dort verwende ich die. Man könnte auch exit benutzten, aber ich verwende hier die. Ich gebe dann, mit der Message "Es gab einen Fehler" noch den mysql_error aus. Dort steht dann drinnen weswegen der Befehl nicht ausgeführt werden konnte. Wie gesagt, das ist hier nicht relevant da man die .php Datei nicht sieht.
    Was man jetzt noch machen muss ist das wichtigste von allen. Man muss die Verbindung zur MySQL Datenbank wieder schließen. Wenn man das nicht machen würde, könnte sich jemand Zugriff darauf verschaffen. Deswegen die Verbindung am Ende des .php Dokuments immer schließen. Jetzt wirst du auch verstehen warum ich $verbindung vor dem mysql_connect gemacht habe. Um eine Verbindung zu schließen benutzt man mysql_close.


    PHP
    mysql_close($verbindung);


    Somit währe der PHP Teil schon fertig. So Kompliziert ist das doch gar nicht wenn man sich das mal stück für stück anschaut.
    Das was wir jetzt noch machen müssen ist der Befehl /pwchange im Script. Das heißt dann also wir gehen jetzt wieder ins Script in den Callback (Public) OnPlayerCommandText und erstellen da erstmal das Grundgerüst des Befehls.


    if(strcmp(cmdtext,"/pwchange",true) == 0)
    {
    return 1;
    }


    Dort lassen wir dann den ersten PWC Dialog anzeigen.


    ShowPlayerDialog(playerid,DIALOG_PWC,DIALOG_STYLE_PASSWORD,"Passwort Change","Gebe nun dein altes Passwort ein","Weiter","Abbrechen");


    Jetzt müssen wir in den Callback (Public) OnDialogResponse und dort folgende Abfrage machen.


    if(response)
    {


    }


    Dort hinein machen wir dann


    if(dialogid == DIALOG_PWC)
    {


    }


    //oder falls du switch benutzt


    case DIALOG_PWC:
    {


    }


    Jetzt kommt die Abfrage vom Passwort wie beim Login. Wenn das eingegebene Passwort mit dem Passwort aus der Datenbank übereinstimmt, kommt folgender Dialog.


    ShowPlayerDialog(playerid,DIALOG_PWC2,DIALOG_STYLE_PASSWORD,"Passwort Change","Gebe nun ein neues Passwort ein","Weiter","");


    Nun wieder dasselbe wie beim Dialog davor, aber mit einer kleinen Änderung.


    if(dialogid == DIALOG_PWC2)
    {
    if(response)
    {

    }
    else ShowPlayerDialog(playerid,DIALOG_PWC2,DIALOG_STYLE_PASSWORD,"Passwort Change","Gebe nun ein neues Passwort ein","Weiter","");
    }


    //oder falls du switch benutzt


    case DIALOG_PWC2:
    {
    if(response)
    {

    }
    else ShowPlayerDialog(playerid,DIALOG_PWC2,DIALOG_STYLE_PASSWORD,"Passwort Change","Gebe nun ein neues Passwort ein","Weiter","");
    }


    Nun kannst die Länge Abfragen, das mache ich jetzt nicht, ich Speichere nur das neue Passwort in die Datenbank.


    new query[100], sName[MAX_PLAYER_NAME];
    GetPlayerName(playerid,sName,sizeof(sName));
    format(query,sizeof(query),"UPDATE `accounts` SET `Passwort`='%s' WHERE `Name`='%s'",MD5_Hash(inputtext) /*Oder WP_Hash(inputtext)*/,sName);
    mysql_query(query);


    Dazu muss ich denke ich mal nicht viel sagen, da das klar sein sollte.
    So, du bist nun am Ende meines Tutorial angelangt. Ich hoffe ich konnte dir das so gut wie möglich erklären. Wenn du dennoch Fragen zu dem Tutorial hast, dann kannst du diese ja hier schreiben, ich werde diese gerne beantworten.


    Wenn du gerne ein Tutorial von mir haben möchtest, bzw. etwas erklärt haben möchtest, dann schreib mir doch eine PN. Ich werde das dann innerhalb von einer Woche in der Tutorial Sektion verwirklichen. Dann wünsche ich dir viel Spaß beim weiteren Scripten.

  • Das ist ein nützlicher Beitrag, Anfängerfreundlich erklärt und überschaubar.


    Aber das Passwort wird ohne eindeutige Identifikation des Spielers geändert, somit kann jeder das Passwort eines Spielers ändern lassen. Dieses Problem wird in Foren oder anderen Portalen umgangen, indem zwei E-Mails versendet werden. In der ersten E-Mail befindet sich ein generierter Link, welcher die Änderung des Passworts übernimmt und eine weitere E-Mail mit dem Passwort an den Spieler sendet. Dadurch, dass der Link nur dem Kontoinhaber bekannt ist, ist auch die Identität des Spielers eindeutig.


    Innovativ & Professionell - Mein Blog





    "Define yourself by your deeds."

  • Danke hat mir sehr weitergeholfen, nur hab ich jetzt ein kleines Problem.
    Wenn ich dieses Funktion hier anwende



    PHP
    mail($email,"Passwort vergessen Funktion",$message,$header);

    sendet der mir keine E-Mail. In PHP bin ich noch nicht so gut :D