2016-04-06 10 views
-2

忘れたパスワード機能を作成するために、最近私はhttp://megarush.net/forgot-password-php/からいくつかのコードを適用しました。私はそれをmysqliに変更し、パスワードを更新する際にいくつかのbcrypt機能を追加しました。短い形式では、ユーザーは電子メールアドレスを入力してリンクを送信し、このリンクを使用してパスワードを更新できますが、もう一度ハッシュされます。 私の問題は...私は、ユーザーに行くための電子メールを得ることができますが、リンクをクリックすると、新しい電子メールアドレスを試しても "無効なリンクまたはパスワードが既に変更されました"と続きます。私が間違っているアイデアは?助けを歓迎します!パスワード機能を忘れた場合はリセットページでエラーが発生する

email,tokenおよびusedのトークンテーブルがあります。

forgot.php

<?php require 'header.php'; 

if (!isset($_GET['email'])) { 
    echo '<form action="forgot.php"> 
     Enter Your Email Id: 
     <input type="text" name="email" /> 
     <input type="submit" value="Reset My Password" /> 
     </form>'; 
    exit(); 
} 

$email = $_GET['email']; 
$sql = "SELECT email FROM user WHERE email='$email'"; 
$query = $mysqli_conn->query($sql); 
if ($query->num_rows == 0) { 
    echo "Email id is not registered"; 
    die(); 
} 

$token = getRandomString(10); 
$sql = "INSERT INTO `tokens` (`token`, `email`) VALUES ('{$token}','{$email}')"; 
$query = $mysqli_conn->query($sql); 

function getRandomString($length) { 
    $validCharacters = "ABCDEFGHIJKLMNPQRSTUXYVWZ123456789"; 
    $validCharNumber = strlen($validCharacters); 
    $result = ""; 
    for ($i = 0; $i < $length; $i++) { 
    $index = mt_rand(0, $validCharNumber - 1); 
    $result.= $validCharacters[$index]; 
    } 
    return $result; 
} 

function mailresetlink($to, $token) { 
    $subject = "Forgot Password"; 
    $uri = 'http://' . $_SERVER['HTTP_HOST']; 
    $message = ' 
    <html> 
    <head> 
    <title>Forgot Password</title> 
    </head> 
    <body> 
    <p>Click on the given link to reset your password <a  
    href="' . $uri . '/project/reset.php?token=' . $token . '">Reset Password</a></p> 

    </body> 
    </html> 
    '; 
    $headers = "MIME-Version: 1.0" . "\r\n"; 
    $headers.= "Content-type:text/html;charset=iso-8859-1" . "\r\n"; 
    $headers.= 'From: Admin<[email protected]>' . "\r\n"; 
    $headers.= 'Cc: [email protected]' . "\r\n"; 
    if (mail($to, $subject, $message, $headers)) { 
    echo "We have sent the password reset link to your email id <b>" . $to . "  
    </b>"; 
    } 
} 

if (isset($_GET['email'])) mailresetlink($email, $token); 
?> 

reset.php

<?php require 'header.php'; 

$token = $_GET['token']; 

if (!isset($_POST['password'])) { 
    $sql = "SELECT email FROM tokens WHERE token='" . $token . "' and used=0"; 
    $query = $mysqli_conn->query($sql); 
    while ($row = mysqli_fetch_array($query)) { 
    $email = $row['email']; 
    } 

    if ($email != '') { 
    $_SESSION['email'] = $email; 
    } 
    else die("Invalid link or Password already changed"); 
} 

$password = $_POST['password']; 
$email = $_SESSION['email']; 

if (!isset($password)) { 
    echo '<form method="post"> 
     enter your new password:<input type="password" name="password" /> 
     <input type="submit" value="Change Password"> 
     </form>'; 
} 

if (isset($_POST['password']) && isset($_SESSION['email'])) { 
    $password = password_hash($password, PASSWORD_DEFAULT); 
    $sql = "UPDATE user SET password= '$password' where email='$email'"; 
    $query = mysqli_query($sql); 
    if ($query) mysqli_query("UPDATE tokens SET used=1 WHERE token='$token'"); 
    echo "Your password is changed successfully"; 
    if (!$query) echo "An error occurred"; 
} 

?> 

UPDATE:無効なエラーが修正さとフォームが表示され、今では単に「と言っ表示されていますエラーが発生しました。すべてのエラーを拾うために、SQLエラーがで追加されました、私が変数をエコーし​​ていると

if (isset($_POST['password']) && isset($_SESSION['email'])) {} 

はなぜあなたのクエリ

+0

localhostでメール機能が動作しない場合は、localhostで試してみてください。 – rummykhan

+0

@rummykhanメールはユーザーに送信されます。クリックしたときに「無効なリンクまたはパスワードが変更されました」というエラーが返されただけのリンクです。私のウェブサイトはサーバー上でホストされています – Jess

+0

ああ申し訳ありませんが、私は再びそれを見てみましょう。 – rummykhan

答えて

2

理由を働いて帰ってくると、それは、パスワードの更新に到達するまで罰金のようです

if (isset($_POST['password']) && isset($_SESSION['email'])) { 
    $password = password_hash($password, PASSWORD_DEFAULT); 
    $sql = "UPDATE user SET password= '$password' where email='$email'"; 
    $query = mysqli_query($sql); 
    if ($query) mysqli_query("UPDATE tokens SET used=1 WHERE token='$token'"); 
    echo "Your password is changed successfully"; 
    if (!$query) echo "An error occurred"; 
} 

あなたがのためにやったのと同じように:あなたはこのコードブロックにある、すべてのmysqli_query()にあなたのDB接続に合格しなかったことにされて発射されていません10。

エラーもチェックしてください。

このif (!$query) echo "An error occurred";はお手伝いしません。

は、それがmysqli_query()には何も、 などor die(mysqli_error($mysqli_conn))を生み出すかどうかを確認するために、その後、例
<?php error_reporting(E_ALL); ini_set('display_errors', 1);のために右のあなたのオープニングPHPの後に、あなたのコードの残りの部分をタグ をお使いのファイルの先頭(複数可)へのエラー報告を追加します。


現在のコードはSQL injectionです。 prepared statements、またはPDOprepared statementsを使用してください。


脚注:

あなたはむしろif ($email != '')よりも条件付きempty()を使用する必要があり、それが良いでしょう。

もう1つのこと:UPDATEを使用する場合は、偽陽性となる可能性があるため、mysqli_affected_rows()を真実に使用することが最適です。ここでhttp://php.net/manual/en/mysqli.affected-rows.php

  • mysqli_affected_rows()を使った例であると私は、パスワードPOSTアレイに!empty()isset()を変更:

    if (!empty($_POST['password']) && isset($_SESSION['email'])) { 
    
        $password = password_hash($password, PASSWORD_DEFAULT); 
        $sql = "UPDATE user SET password= '$password' where email='$email'"; 
        $query = mysqli_query($mysqli_conn, $sql) or die(mysqli_error($mysqli_conn)); 
    
        if (mysqli_affected_rows($mysqli_conn)){ 
        mysqli_query($mysqli_conn, "UPDATE tokens SET used=1 WHERE token='$token'"); 
    
         echo "Your password is changed successfully"; 
        } 
        else { 
        echo "An error occured: " . mysqli_error($mysqli_conn); 
        } 
    
    
    } 
    

    編集:

    変更するには、このブロック全体:

    $token = $_GET['token']; 
    
    if (!isset($_POST['password'])) { 
        $sql = "SELECT email FROM tokens WHERE token='" . $token . "' and used=0"; 
        $query = $mysqli_conn->query($sql); 
        while ($row = mysqli_fetch_array($query)) { 
        $email = $row['email']; 
        } 
    
        if ($email != '') { 
        $_SESSION['email'] = $email; 
        } 
        else die("Invalid link or Password already changed"); 
    } 
    

    (今の場合)、このコードブロックを取り除くつつ:

    if ($email != '') { 
    $_SESSION['email'] = $email; 
    } 
    else die("Invalid link or Password already changed"); 
    

    で置換される上記最初のコードブロック及び行がmysqli_num_rows()で存在するかどうかをチェック:

    if (isset($_GET['token'])) { 
    
    $token = $_GET['token']; 
    
    $sql = "SELECT email FROM tokens WHERE token='" . $token . "' and used=0"; 
    $query = $mysqli_conn->query($sql) or die(mysqli_error($mysqli_conn)); 
    
        if(mysqli_num_rows($query) > 0){ 
    
         while ($row = mysqli_fetch_array($query)) { 
    
          $email = $row['email']; 
          $_SESSION['email'] = $email; 
    
         } 
    
        } 
    
    } 
    
+0

ありがとうございます。私はあなたの提案を述べたように私の接続変数を追加しようとしましたが、メール機能はユーザーに電子メールを送信せず、空白のテキストボックスが表示されます。私はまた、エラー報告と何も示してみましたか? – Jess

+0

@Jessようこそ。私は、メール機能がこれと何をするのか理解できません。 –

+0

私のウェブサイトのリンクを送ることはできますか?私はforgot.phpのコードを変更していないので、私は理解できません。 – Jess

関連する問題