Frage zum Programmablauf und Sicherheit

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • Frage zum Programmablauf und Sicherheit

    Ich habe eine Internetseite. Auf dieser müssen sich bestehende Kunden identifizieren. D.h. ich habe schon Name, Adresse Email usw. diese müssen nur eben von den richtigen Leuten verifiziert werden.
    Soweit der Plan.
    Nun habe ich folgenden Ablauf
    1. Der Kunde füllt ein Formular mit Kundennummer. Name, Adresse, Telefon und Email Adresse aus und schickt es zu mir.
    2. Ich überprüfe die Angaben und sende dem Kunden ein Passwort zu.
    3. Der Kunde muss beim 1. Login das Passwort ändern und das neue Passwort wird in der Datenbank eingetragen.
    Nun zu den einzelnen Skripten:

    Zugangsdaten anfordern:
    PHP-Code:
    <?
    include_once $_SERVER['DOCUMENT_ROOT'] . '/securimage/securimage.php';
    $securimage = new Securimage();
    ?>
    <text class="span">Zugangsdaten anfordern</text><br />
    <? if(!isset($_SESSION["zugang1"])) { ?>

    Sie hätten also gerne Zugang zu ihren Daten. - Kein Problem. Als erstes müssen wir ihre Identität klären. Dazu benötigen wir einige Daten von ihnen. Ich überprüfe ihre Daten und senden ihnen ein Einmlapasswort per Email zu.
    <br /><br />
    <text class="span">Persönliche Daten</text><br />
    <script type="text/javascript">
    function validate_num(formdata) {
      formdata.value=formdata.value.replace(/\D/, '' );
    }
    function validate_num1(formdata) {
      formdata.value=formdata.value.replace(/\D/, '' );
    }
    </script>
    <center><u>Alle * Felder müssen Aus</u>g<u>efüllt werden</u></center>
    <form action="" method="POST">
    <table width="100%" cellspacing="10"><tr>
    <td width="150px" align="right">Ihr Nachname: *</td>
    <td><input id="inputs2" type="text" name="nachname" style="width:300px" required /></td><tr>
    <td width="150px" align="right">Ihr Vorname: *</td>
    <td><input id="inputs2" type="text" name="vorname" style="width:300px" required /></td><tr>
    <td width="150px" align="right">Strasse / HsNr: *</td>
    <td><input id="inputs2" type="text" name="strasse" style="width:247px" required /><input id="inputs2" type="text" name="hsnr" style="width:50px" required /></td><tr>

    <td width="150px" align="right">PLZ / Wohnort: *</td>
    <td><input id="inputs2" type="text" name="plz" onkeyup="validate_num(this);" style="width:60px" required /><input id="inputs2" type="text" name="ort" style="width:237px" required /></td><tr>

    <td width="150px" align="right">Telefon Festnetz: (optional)</td>
    <td><input id="inputs2" type="text" name="telefon_vorwahl" style="width:80px" placeholder="Vorwahl" /> <input id="inputs2" type="text" name="telefon2" style="width:120px" placeholder="Nummer" /></td><tr>

    <td width="150px" align="right">Email Adresse: *</td>
    <td><input id="inputs2" type="email" name="email" style="width:250px" placeholder="Ihre Email-Adresse" required /></td><tr>



    <td width="150px" align="right">Ihre Kundenummer: *</td>
    <td valign="top"><input id="inputs2" type="text" onkeyup="validate_num1(this);" pattern="[0-9]{1}" name="kundenummer" min="100" style="width:60px" required /> <br />(Auf Rechnungen oder Angeboten / 3-stellig)</td><tr>


    <td width="150px" align="right">Captcha: *</td>
    <td valign="top" align="left"><img id="captcha" src="/securimage/securimage_show.php" alt="CAPTCHA Image" /><br />
    <input type="text" name="captcha_code" size="10" maxlength="6" />

    <a href="#" onclick="document.getElementById('captcha').src = '/securimage/securimage_show.php?' + Math.random(); return false">[ Bild neu laden ]</a></td><tr>

    </table>
    <br />
    <center><input type="submit" name="verify" value="Absenden" style="padding:10px;" /></center>


    <? } else { echo "<center>Sie haben bereits einmal einen Zugangsversuch gestartet !<br /><br /></center>"; exit; }

    ?></form><?


    if(isset($_POST["verify"])) {
        


            if ($securimage->check($_POST['captcha_code']) == false) {
            echo "<br /><br /><center><span style='padding:10; border:1px solid red;'>Der eingegebene Captcha-Code ist nicht korrekt. Bitte versuchen Sie es erneut.</span></center>";
            exit;
            }
            
        $kdnr = filter_var($_POST["kundenummer"], FILTER_VALIDATE_INT);
        $nachname = filter_var($_POST["nachname"], FILTER_SANITIZE_STRING);
        $vorname = filter_var($_POST["vorname"], FILTER_SANITIZE_STRING);
        $strasse = filter_var($_POST["strasse"], FILTER_SANITIZE_STRING);
        $hsnr = filter_var($_POST["hsnr"], FILTER_SANITIZE_STRING);
        $plz = filter_var($_POST["plz"], FILTER_VALIDATE_INT);
        $ort = filter_var($_POST["ort"], FILTER_SANITIZE_STRING);
        $telefon1 = strip_tags($_POST["telefon_vorwahl"]);
        $telefon2 = strip_tags($_POST["telefon2"]);
        $email = filter_var($_POST["email"], FILTER_VALIDATE_EMAIL);
        
        $random = RandomToken();
        
        $empfaenger = "info@zwpc.de"; 
        $absender   = "Computerservice Blasius Thomas <info@zwpc.de>";
        $betreff    = utf8_decode("Bestätigungslink Kundenlogin");
        $antwortan  = "info@zwpc.de";
     
        $header  = "MIME-Version: 1.0\r\n";
        $header .= "Content-type: text/html; charset=iso-8859-1\r\n";
     
        $header .= "From: $absender\r\n";
        $header .= "Reply-To: $antwortan\r\n";
        $header .= "X-Mailer: PHP ". phpversion();
        $mailtext = utf8_decode('<html>
            <head>
            <title>Bestätigungslink für '.$nachname.' '.$vorname.'</title>
            </head>
            <style txpe="text/css">
            body{ background:#454545; color:#fff; font-family:Arial, Helvetica, sans-serif;}
            a { text-decoration:none; color:#7079F7; }

            </style>
                
            <body>
            Ein Kunde hat Zugang zum Kundencenter beantragt !
            <br />
            Zugangsanforderung von:<hr>
            KDNR: '.$kdnr.'<br />
            Name: '.$nachname.' '.$vorname.'<br />
            Strasse: '.$strasse.' '.$hsnr.'<br />
            Ort: '.$plz.' '.$ort.'<br />
            Telefon: '.$telefon1.' / '.$telefon2.'<br />
            Email: '.$email.'<br />
            <br /><hr>
            <a href="http://www.zwpc.de/aktivierung.php?email='.$email.'&vorname='.$vorname.'&nachname='.$nachname.'&kdnr='.$kdnr.'"> -= Account bestätigen =-</a>

    </body>
    </html>
    ');
    mail( $empfaenger,
          $betreff,
          $mailtext,
          $header);
          
          $_SESSION["zugang1"] = "Ja";
          
          ?>
          <script language="javascript">alert('Wir haben ihre Daten erhalten und werden ihr Anliegen umgehend bearbeiten');</script>
          <meta http-equiv="refresh" content="0; URL=/startseite">
          <?

          
        } 
    ?>
    Die Aktivierung:

    PHP-Code:
    <?
    error_reporting(-1);
    ini_set('display_errors', true);

        include 'db/conn.php';
        
    function zufallsstring($laenge) {
       $zeichen = '0123456789';
       $zeichen .= 'abcdefghijklmnopqrstuvwxyz';
       $zeichen .= 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
       $zeichen .= '()!.:=';

       $str = '';
       $anz = strlen($zeichen);
       for ($i=0; $i<$laenge; $i++) {
          $str .= $zeichen[rand(0,$anz-1)];
       }
       return $str;
    }
        
        $kdnr = filter_input(INPUT_GET, 'kdnr', FILTER_VALIDATE_INT);
        $email = filter_input(INPUT_GET, 'email', FILTER_VALIDATE_EMAIL);
        $vorname = filter_input(INPUT_GET, 'vorname', FILTER_SANITIZE_SPECIAL_CHARS);
        $nachname = filter_input(INPUT_GET, 'nachname', FILTER_SANITIZE_SPECIAL_CHARS);

        
        $passwort1 = zufallsstring(8); 
        $passwort2 = password_hash($passwort1, PASSWORD_DEFAULT);
        
        $mysqli->query("UPDATE kunden SET passwort = '$passwort2' WHERE kdnr = '$kdnr'");
        
        $empfaenger = $email; 
        $absender   = "info@xxx.de";
        $betreff    = utf8_decode("Bestätigungslink Kundenlogin");
        $antwortan  = "info@zwpc.de";
     
        $header  = "MIME-Version: 1.0\r\n";
        $header .= "Content-type: text/html; charset=iso-8859-1\r\n";
     
        $header .= "From: $absender\r\n";
        $header .= "Reply-To: $antwortan\r\n";
        $header .= "X-Mailer: PHP ". phpversion();
        $mailtext = utf8_decode('<html>
            <head>
            <title>Bestätigungslink für '.$nachname.' '.$vorname.'</title>
            </head>
            <style txpe="text/css">
            body{ background:#454545; color:#fff; font-family:Arial, Helvetica, sans-serif;}
            a { text-decoration:none; color:#7079F7; }

            </style>
                
            <body>
    <hr>
            Hallo '.$nachname.' '.$vorname.',<br />
            <br />
            Ich habe ihre Daten geprüft und ihren Zugang zum Kundencenter freigeschaltet.<br /><br />Ihr Einmalpasswort lautet: <b>'.$passwort1.'</b><br />
            <br />Dieses Passwort ist Einmalig und nur zum ersten Login gültig. Sie werden beim ersten Zugang ins Kundencenter zum Wechseln ihres Passworts aufgefordert. Bitte merken Sie sich dieses Passwort gut oder Notieren Sie es sich. Ich kann ihr Passwort weder sehen noch bei Verlust wiederherstellen !<hr>
            <br /><br />Loggen Sie sich nun hier ein: <a href="http://www.xxx.de"> -= Zur Webseite =-</a>
    <br /><br />Mit freundlichen Grüssen<br />
     
    </body>
    </html>
    ');
    mail( $empfaenger,
          $betreff,
          $mailtext,
          $header);
        
        
        
        echo "<h2>Zugang bestätigt !</h2>";
        ?>

  • #2
    2. Teil

    Das normale und erste Login:

    PHP-Code:
    <? login_check(); ?>
    <h3>Kundencenter ist im Aufbau !</h3>
    <? 
    include_once $_SERVER['DOCUMENT_ROOT'] . '/securimage/securimage.php';
    $securimage = new Securimage();
    $result = $mysqli->query("SELECT * FROM kunden WHERE kdnr = '".$_SESSION["kdnr"]."'");
    $row = $result->fetch_array(MYSQLI_ASSOC);

    if(!empty($row["firma"])) { $e_anrede = "Willkommen, Firma ".$row["firma"]; } else { $e_anrede = "Willkommen, ".$row["anrede"]." ".$row["nachname"]." ".$row["vorname"]; }
    echo "<br />Willkommen " . $row["anrede"] . " " .$row["nachname"] . " " . $row["vorname"]."<hr>";
    if($row["firstlogin"] == 0 && $row["email"] != '') { // Die Prüfung auf Email ist unnötig ??
    ?>
    <br />Dies ist ihr erstes Login im Kundencenter. Bitte ändern Sie nun ihr Passwort !<br /><br />
    <form action="" method="POST">
    <table width="100%" cellpadding="10"><tr>
    <td width="300px" align="right">Bitte geben Sie ihr Einmalpasswort ein:</td>
    <td><input type="text" id="inputs2" style="width:250px" name="einmalpass" /></td><tr>
    <td width="300px" align="right">Bitte geben Sie ein neues Kennwort ein:</td>
    <td><input type="password" id="inputs2" style="width:250px" name="pass1" /></td><tr>
    <td width="300px" align="right">Bitte wiederholen Sie ihr neues Kennwort:</td>
    <td><input type="password" id="inputs2" style="width:250px" name="pass2" /></td><tr>
    <td width="300px" align="right"></td>
    <td><input type="submit" style="padding:10px" name="eintrag" value="Absenden" /></td><tr>
    </table>
    <?
    }
    else {    
        echo "<br />Ich arbeite gerade am neuen Kundencenter !";
        
    }
    if(isset($_POST["eintrag"])) {
        
        $result3 = $mysqli->query("SELECT passwort FROM kunden WHERE kdnr = '".$_SESSION["kdnr"]."'");
        $row3 = $result3->fetch_array(MYSQLI_ASSOC);
        
        $pass_alt = $row3["passwort"];
        $einmalpass = $_POST["einmalpass"];
        
        if(password_verify($einmalpass, $pass_alt)) {

        $pass1 = $_POST["pass1"];
        $pass2 = $_POST["pass2"];
        
        $fehler = 0;
        $text = "";
        
        if( strlen( $pass1 )<8 ) { $fehler = 1; $text .= "<br />Kennwort 1 hat weniger als 8 Zeichen"; }
        if( strlen( $pass2 )<8 ) { $fehler = 1; $text .= "<br />Kennwort 2 hat weniger als 8 Zeichen"; }
        if($pass1 != $pass2) { $fehler = 1; $text .= "<br />Die Passwörter stimmen leider nicht überein !"; }

        if($fehler == 0) {
        $kdnr = $_SESSION["kdnr"];
        $pass_hash = password_hash($pass2, PASSWORD_DEFAULT);
        
        $mysqli->query("UPDATE kunden SET passwort = '$pass_hash', firstlogin = '1' WHERE kdnr = '$kdnr'");
        ?>
          <script language="javascript">alert('Das Passwort wurde geändert. Sie werden nun weitergeleitet...');</script>
          <meta http-equiv="refresh" content="0; URL=/startseite">
          <?
        } else { echo "<p style='padding:10px; border:2px dotted red;'>Folgende Fehler sind aufgetreten:<br />".$text."</p>"; }
        
        } else { echo "<br /><center>Ihr Einmalpasswort stimmt leider nicht ! Bitte versuchen Sie es erneut.</center>"; exit; }
        
        
    } ?>
    Welche Verbesserungen kann man Einbauen / Habe ich was Vergessen ?

    Kommentar


    • #3
      Du solltest in jedem Fall noch mal insbesondere die Groß-/Kleinschreibung in deinen Texten checken. Anredeformen wie „Ihre“ werden groß geschrieben, Verben werden klein geschrieben, „Einmlapasswort“, Plenks.

      Dann würde ich darüber nachdenken, eine Mailerklasse wie PHPMailer oder Swift Mailer zu nutzen.

      Zudem solltest du in deinem Code den Grundsatz beachten, sämtliche Verarbeitung vor dem Beginn der Ausgabe durchzuführen, da der Code sonst schwierig lesbar ist und du in logische Zwickmühlen laufen könntest (Fehler wird erst dann erkannt, wenn „normale“ HTML-Ausgabe schon begonnen hat).

      In sich geschlossene Code-Teile (etwa das Versenden von Mails) können zumindest in Funktionen ausgelagert werden, was die Lesbarkeit weiter erhöht.

      Welche Verbesserungen kann man Einbauen / Habe ich was Vergessen ?
      So was ist auf konzeptioneller Ebene immer kaum sinnvoll zu beantworten, weil nur du deine Anforderungen kennst. Eine Sache ist, dass ich im Bestätigungslink (der kein korrektes HTML ist, weil du die Kontextwechsel nach HTML nicht beachtest; &→&amp; und dergleichen, htmlspecialchars) nicht die echten Daten der Nutzer angeben würde, sondern ein Token erstellen würde, dem serverseitig dann der passende Account zugeordnet ist.

      example.org/activate?token=<randomstring>

      Kommentar


      • #4
        Re

        Endlich mal einer der eine vernünftige Antwort parat hat. Nicht immer dieses schau da und schau da und Google halt... ^^

        Rechtschreibung ist klar, wird noch gecheckt wenn alles soweit ist.
        Mailer Klasse ist soweit auch schon in Arbeit.
        Ich denke ich lagere noch einige Sachen in Funktionen aus bisher ist wieklich alles ein wenig Verwirrend.

        Das mit dem Links - sowas meinte ich - besten Dank. Arbeite ich nach.

        Kommentar


        • #5
          Re

          Kurze Zwischenfrage: Was ist besser oder sicherer oder ist das egal ?

          A) $passwort = hash('sha512', $passwort.salt); oder
          B) password_hash($passwort, PASSWORD_DEFAULT);

          Kommentar


          • #6
            Grundsätzlich ist password_hash the way to go.

            In jedem Fall aber mal die Doku lesen, falls du es noch nicht gemacht hast. Das Thema ist traditionell etwas knifflig.

            - PHP: password_hash - Manual

            Kommentar


            • #7
              re

              Ich denke password_hash wird wohl die Zukünftige Verschlüsselung.
              Bislang:

              Login Seite:
              PHP-Code:
              if(isset($_POST["login_5_1"])) {
                  
                  if(isset(
              $_POST["kdnr"], $_POST["email"], $_POST["passwort"])) {
                  
                  
              // Eingaben Filtern //
                  
              $kd_kdnr filter_input(INPUT_POST'kdnr'FILTER_SANITIZE_NUMBER_INT);
                  
              $kd_email filter_input(INPUT_POST'email'FILTER_SANITIZE_EMAIL);
                  
              $kd_email filter_var($kd_emailFILTER_VALIDATE_EMAIL);
                  
                      
                      if (!
              filter_var($kd_emailFILTER_VALIDATE_EMAIL)) {
                      echo 
              "<br /><center><font size='0.8em' color:red'>Keine gültige Email Adresse</font></center>";
                      exit;
                      }
                      
                      
                  
              $kd_passwort filter_input(INPUT_POST'passwort'FILTER_SANITIZE_STRING);
                  
                      
              // Passwortlänge checken
                      
              if (strlen($kd_passwort) < 6) {
                      echo 
              "<br /><center><font size='0.8em' color:red'>Das Passwort ist zu kurz !</font></center>";
                      exit;
                      }
                          
              // Login ausführen
                          
              if(login($kd_kdnr$kd_email$kd_passwort$mysqli) === true) {
                          
              header('location: /kundencenter');
                          } else {
                          
              header('location: /fehlerseite');
                          }

                  } else { echo 
              "Es fehlen Angaben !"; }

              }
               
               if(isset(
              $_POST["logout"])) {
                  
              logout($mysqli);
               } 
              Funktion Login:

              PHP-Code:
              function login($kd_kdnr$kd_email$kd_passwort$mysqli) {
                  if (
              $stmt $mysqli->prepare("SELECT kdnr, email, passwort FROM kunden WHERE kdnr = ? AND email = ? LIMIT 1")) {
                      
              $stmt->bind_param('is'$kd_kdnr$kd_email);  
                      
              $stmt->execute();   
                      
              $stmt->store_result();

                      
              $stmt->bind_result($db_kdnr$db_email$db_passwort);
                      
              $stmt->fetch();
                  
                      if (
              $stmt->num_rows == 1) {

                              if (
              password_verify($kd_passwort$db_passwort)) {
                                  
                                  
              $time_now time();
                                  
              $datum date("d.m.Y"time());
                                  
              $uhrzeit date("H:i"time());
                                  
                                  
              // Sicherheitstoken erstellen, in Session speichern und in DB eintragen
                                  
              $token =  password_hash($time_nowPASSWORD_DEFAULT);
                                  
              $_SESSION["token"] = $token;
                                  
              $_SESSION["kdnr"] = $db_kdnr;
                                                  
                                  
              $mysqli->query("UPDATE kunden SET token = '$token' WHERE kdnr = '$db_kdnr'");

                                  
              // Eintragen dass KD sich angemeldet hat
                                  
              $mysqli->query("INSERT INTO logins(kdnr,email,datum,uhrzeit,timestamp,status)
                                                  VALUES ('
              $db_kdnr','$db_email','$datum','$uhrzeit','$time_now','Login OK')");
                                  
                                  return 
              true;
                              } else {
                                  
                                  
              $time_now time();
                                  
              $datum date("d.m.Y"time());
                                  
              $uhrzeit date("H:i"time());
                                  
                                  
              // Fehlgeschlagener Login in DB eintragen
                                  
              $mysqli->query("INSERT INTO logins(kdnr,email,datum,uhrzeit,timestamp,status)
                                                  VALUES ('
              $db_kdnr','$db_email','$datum','$uhrzeit','$time_now','Falsches Passwort')");
                                  return 
              false;
                              }
                          
                      } else {
                          
              $_SESSION["fehler"] .= "Es gibt leider keinen Benutzer mit dieser Kennungskombination !";
                          return 
              false;
                      }
                  }

              Funktion Login Check:

              PHP-Code:
              function login_check($mysqli) {
                  if (isset(
              $_SESSION['kdnr'], $_SESSION['token'])) {
                      
                      
              $se_kdnr $_SESSION['kdnr'];
                      
              $se_token $_SESSION['token'];

                      if (
              $stmt $mysqli->prepare("SELECT passwort, token FROM kunden WHERE kdnr = ? AND token = ? LIMIT 1")) {
                          
              $stmt->bind_param('is'$se_kdnr$se_token);
                          
              $stmt->execute();  
                          
              $stmt->store_result();
               
                          if (
              $stmt->num_rows == 1) {

                              
              $stmt->bind_result($db_passwort$db_token);
                              
              $stmt->fetch();
                              if (
              $se_token === $db_token) {
                                  return 
              true;
                              } else {
                                 echo 
              "Token falsch"
                                  return 
              false;
                              }
                          } else {
                              echo 
              "Keinen Benutzer gefunden !"
                              return 
              false;
                          }
                      } else {
                         echo 
              "Fehler mit DB Abfrage in login_check";
                          return 
              false;
                      }
                  } else {
                      echo 
              "<center><font size='0.8em'>Sie sind nicht angemeldet</font></center>";
                      return 
              false;
                  }

              Derzeit geht nur der Eintrag bei Login (Login -OK oder Login False) noch nicht und ich weiss nicht genau warum. Dürfen keine 2 $mysqli Abfragen hinternander stehen ?

              Kommentar


              • #8
                re

                Fehler beim Eintrag gefunden. Mal wieder ein Fehlendes '

                Kommentar


                • #9
                  Ich habe die login()-Funktion mal rausgegriffen und ein wenig kommentiert/verändert.

                  Da fehlte Escaping.

                  Allgemeiner Tipp: Verwende Guard-Clauses und lagere Code gegebenenfalls in weitere Methoden/Funktionen aus, statt ihn tief zu schachteln. Ich habe das für die nachfolgende Funktion ein wenig ergänzt.

                  So was wie die $log-Closure ist ein einfacher Weg, zu viel Redundanz auch innerhalb von Methoden/Funktionen zu vermeiden, wenn einem gerade nicht einfällt, wie man das sinnvoller anlegen könnte. Ist aber mehr oder weniger Erfahrungs- oder Geschmackssache. Inflationär würde ich so was auch nicht nutzen, aber es trägt zur Strukturierung bei.

                  (Ich konnte es nicht testen, muss also nicht alles 100 % korrekt sein.)

                  PHP-Code:
                  // Wieso benötigt diese Funktion die `kdnr` und die `email`? Sind beide Merkmale
                  // beim Login anzugeben? Also insgesamt `kdnr`, `email` und `passwort`?
                  function login($kd_kdnr$kd_email$kd_passwortmysqli $mysqli)
                  {
                      
                  // Es würde reichen, den aktuellen Zeitpunkt in *einer* Repräsentation
                      // abzulegen (DATETIME-Spalte). Es ist möglicherweise redundant, die
                      // E-Mail-Adresse abzulegen, da die gegebenenfalls vermutlich über die
                      // `kdnr` ermittelt werden kann
                      
                  $log = function ($db_kdnr$db_email$message) use ($mysqli) {
                          
                  $time_now time();
                          
                  $datum    date("d.m.Y"time());
                          
                  $uhrzeit  date("H:i"time());

                          
                  $mysqli->query("
                              INSERT INTO logins
                                  (
                                      kdnr, email, datum, uhrzeit, timestamp, status
                                  )
                              VALUES
                                  (
                                      '" 
                  $mysqli->real_escape_string($db_kdnr)  . "',
                                      '" 
                  $mysqli->real_escape_string($db_email) . "',
                                      '" 
                  $mysqli->real_escape_string($datum)    . "',
                                      '" 
                  $mysqli->real_escape_string($uhrzeit)  . "',
                                      '" 
                  $mysqli->real_escape_string($time_now) . "',
                                      '" 
                  $mysqli->real_escape_string($message)  . "'
                                  )
                          "
                  );
                      };

                      
                  // Ähnliche Frage wie zur Funktion insgesamt: Wieso `kdnr` und `email`?

                      
                  $stmt $mysqli->prepare("
                          SELECT kdnr, email, passwort
                          FROM   kunden
                          WHERE  kdnr = ? AND email = ?
                          LIMIT  1
                      "
                  );

                      if (!
                  $stmt instanceof mysqli_stmt) {
                          return 
                  false;
                      }

                      
                  $stmt->bind_param('is'$kd_kdnr$kd_email);
                      
                  $stmt->execute();
                      
                  $stmt->store_result();

                      
                  $stmt->bind_result($db_kdnr$db_email$db_passwort);
                      
                  $stmt->fetch();

                      if (
                  !== $stmt->num_rows) {
                          
                  $_SESSION["fehler"] .= "Es gibt leider keinen Benutzer mit dieser Kennungskombination !";

                          return 
                  false;
                      }

                      if (
                  true !== password_verify($kd_passwort$db_passwort)) {
                          
                  // Fehlgeschlagener Login in DB eintragen
                          
                  $log($db_kdnr$db_email'Falsches Passwort');

                          return 
                  false;
                      }

                      
                  // Sicherheitstoken erstellen, in Session speichern und in DB eintragen

                      // Ich weiß nicht, ob das hier eine sinnvolle Variante ist, Tokens zu
                      // generieren, habe aber spontan keinen besseren simplen Vorschlag
                      
                  $token password_hash(time(), PASSWORD_DEFAULT);

                      
                  $_SESSION["token"] = $token;
                      
                  $_SESSION["kdnr"]  = $db_kdnr;

                      
                  $mysqli->query("
                          UPDATE kunden
                          SET    token = '" 
                  $mysqli->real_escape_string($token) . "'
                          WHERE  kdnr = '" 
                  $mysqli->real_escape_string($db_kdnr) . "'
                      "
                  );

                      
                  // Eintragen, dass Kunde sich angemeldet hat

                      
                  $log($db_kdnr$db_email'Login OK');

                      return 
                  true;

                  Zuletzt geändert von mermshaus; 09.05.2016, 00:19.

                  Kommentar


                  • #10
                    re

                    Es müssen Kundenummer, Email und Passwort beim Login angegeben werden.

                    KDNR und Email weil das die beiden (zumindest eins davon) eindeutig Einzigartigsten Werte sind.
                    1. Der Kunde registriert sich für den Zugang. Eingaben werden geprüft:
                    PHP-Code:
                        $kdnr filter_input(INPUT_POST'kundenummer'FILTER_SANITIZE_NUMBER_INT);
                        
                    $nachname filter_input(INPUT_POST'nachname'FILTER_SANITIZE_STRING);
                        
                    $vorname filter_input(INPUT_POST'vorname'FILTER_SANITIZE_STRING);
                        
                    $strasse filter_input(INPUT_POST'strasse'FILTER_SANITIZE_STRING);
                        
                    $hsnr filter_input(INPUT_POST'hsnr'FILTER_SANITIZE_STRING);
                        
                    $plz filter_input(INPUT_POST'plz'FILTER_SANITIZE_NUMBER_INT);
                        
                    $ort filter_input(INPUT_POST'ort'FILTER_SANITIZE_STRING);
                        
                    $telefon1 filter_input(INPUT_POST'telefon1'FILTER_SANITIZE_NUMBER_INT);
                        
                    $telefon2 filter_input(INPUT_POST'telefon2'FILTER_SANITIZE_NUMBER_INT);
                        
                    $email filter_input(INPUT_POST'email'FILTER_SANITIZE_EMAIL);
                        
                        
                    $stmt $mysqli->prepare("SELECT anrede, firma, nachname, vorname FROM kunden WHERE kdnr = ?");
                        
                    $stmt->bind_param('is'$kdnr$email);
                        
                    $stmt->execute();
                        
                    $stmt->store_result();
                        echo 
                    $stmt->num_rows();
                        if(
                    $stmt->num_rows == 0) { echo "<br /><br /><center><span style='padding:10; border:1px solid red;'>Leider gibt es keinen Benutzer mit dieser Kundenummer / E-Mail Adresse</span></center>"; exit; } 
                    Wenn Kundenummer vorhanden (Musste Email rausnehmen da es auch Kunden ohne eingetragende Email gibt) generiere ich ein Token:
                    PHP-Code:
                    $random RandomToken();
                        
                    $serial password_hash($randomPASSWORD_DEFAULT); 
                    mit
                    PHP-Code:
                    function RandomToken($length 32){
                        if(!isset(
                    $length) || intval($length) <= ){
                          
                    $length 32;
                        }
                        if (
                    function_exists('random_bytes')) {
                            return 
                    bin2hex(random_bytes($length));
                        }
                        if (
                    function_exists('mcrypt_create_iv')) {
                            return 
                    bin2hex(mcrypt_create_iv($lengthMCRYPT_DEV_URANDOM));
                        } 
                        if (
                    function_exists('openssl_random_pseudo_bytes')) {
                            return 
                    bin2hex(openssl_random_pseudo_bytes($length));
                        }

                    und schicke das Formular an mich:
                    PHP-Code:
                    $empfaenger "-------"
                        
                    $absender   "<------>";
                        
                    $betreff    utf8_decode("Bestätigungslink Kundenlogin");
                        
                    $antwortan  "-------";
                     
                        
                    $header  "MIME-Version: 1.0\r\n";
                        
                    $header .= "Content-type: text/html; charset=iso-8859-1\r\n";
                     
                        
                    $header .= "From: $absender\r\n";
                        
                    $header .= "Reply-To: $antwortan\r\n";
                        
                    $header .= "X-Mailer: PHP "phpversion();
                        
                    $mailtext utf8_decode('<html>
                            <head>
                            <title>Bestätigungslink</title>
                            </head>
                            <style txpe="text/css">
                            body{ background:#454545; color:#fff; font-family:Arial, Helvetica, sans-serif;}
                            a { text-decoration:none; color:#7079F7; }

                            </style>
                                
                            <body>
                            Ein Kunde hat Zugang zum Kundencenter beantragt !
                            <br />
                            Zugangsanforderung von:<hr>
                            KDNR: '
                    .$kdnr.'<br />
                            Name: '
                    .$nachname.' '.$vorname.'<br />
                            Strasse: '
                    .$strasse.' '.$hsnr.'<br />
                            Ort: '
                    .$plz.' '.$ort.'<br />
                            Telefon: '
                    .$telefon1.' / '.$telefon2.'<br />
                            Email: '
                    .$email.'<br />
                            <br /><hr>
                            <a href="http://--------/aktivierung.php?token='
                    .$serial.'"> -= Account bestätigen =-</a>

                    </body>
                    </html>
                    '
                    );
                    mail$empfaenger,
                          
                    $betreff,
                          
                    $mailtext,
                          
                    $header);
                          
                          
                    $mysqli->query("UPDATE kunden SET aktivierungstoken = '$serial', acc_aktiviert = '0' WHERE kdnr = '$kdnr'"); 
                    Die versuchte Mailer Klasse wollte gestern Abend so rein garnix machen deswegen nochmal mail()

                    Kann man eine header Weiterleitung anders schreiben. Leider will er nach dem Login die Weiterleitung nicht machen da wohl header schonmal ausgeführt wurde. "Connot header modify...."
                    Hab es derzeit mit "<meta refresh...." umgangen
                    Zuletzt geändert von thommy1972de; 09.05.2016, 06:57.

                    Kommentar


                    • #11
                      Wenn zwei Kunden nicht die gleiche Kundennummer haben können, reicht auch die Kundennummer, um einen Kunden eindeutig zu identifizieren. Nur so als Anmerkung.

                      Kann man eine header Weiterleitung anders schreiben. Leider will er nach dem Login die Weiterleitung nicht machen da wohl header schonmal ausgeführt wurde. "Connot header modify...."
                      Hab es derzeit mit "<meta refresh...." umgangen
                      Beginn die Ausgabe/Rückgabe erst, wenn klar ist, wie sie aussehen soll. Wenn du schon Ausgabe machst und dann irgendwann feststellst, dass du eigentlich eine header-Weiterleitung willst, ist der Code einfach falsch strukturiert.

                      Stichwort EVA-Prinzip:

                      - EVA Prinzip - PHP Forum: phpforum.de
                      - EVA-Prinzip (Standardverfahren) PHP.de Wissenssammlung

                      Kommentar


                      • #12
                        re

                        Da ich aber gerne von allen Kunden eine Email Adresse hätte werde ich die mit Abfragen.

                        Weiterleitung erstmal umgangen:

                        PHP-Code:
                        function umleitung($filename) {
                            if (!
                        headers_sent())
                                
                        header('Location:'.$filename);
                            else {
                                echo 
                        '<script type="text/javascript">';
                                echo 
                        'window.location.href="'.$filename.'";';
                                echo 
                        '</script>';
                                echo 
                        '<noscript>';
                                echo 
                        '<meta http-equiv="refresh" content="0;url='.$filename.'" />';
                                echo 
                        '</noscript>';
                            }

                        Zuletzt geändert von thommy1972de; 10.05.2016, 08:17.

                        Kommentar


                        • #13
                          Die E-Mail-Adresse kannst du als Datum natürlich erheben. Das ergibt ja völlig Sinn.

                          Mir geht es darum, dass die E-Mail-Adresse in Queries wie dieser (die ist von dir, nur etwas umformatiert) nicht im WHERE-Teil auftauchen muss/sollte:

                          PHP-Code:
                              $stmt $mysqli->prepare("
                                  SELECT kdnr, email, passwort
                                  FROM   kunden
                                  WHERE  kdnr = ? AND email = ?
                                  LIMIT  1
                              "
                          ); 

                          Kommentar


                          • #14
                            re

                            Aber dann müsste ich doch folglich ohne die Email Abfrage 2 IF Bedingungen erstellen ?
                            PHP-Code:
                            if(password_verify(.... 
                            und
                            PHP-Code:
                            if($kd_email == $db_email) .... 
                            oder kann ich das alles in eine Abfrage packen ?
                            PHP-Code:
                            if($db_email == $kd_email && password_verify($db_passwort$kd_passwort)) { ..... 
                            ??

                            Kommentar


                            • #15
                              Mir geht es mehr oder weniger darum, dass für einen Login-Vorgang nicht Kundennummer und E-Mail-Adresse und Passwort als Eingaben benötigt werden müssen. Die E-Mail-Adresse kann man natürlich zusätzlich fordern, aber das scheint mir doch eher unüblich zu sein.

                              Kommentar

                              Lädt...
                              X