パスワードを忘れた場合、ユーザーに新しいパスワードを入力して変更し、ログインできるようにする。

全体像

HTMLフォーム

ps_input_view.php
<p>下記項目を入力して、「次へ」でお進みください。</p>
<form action="" method="post" class="login_input">
<input type="text" name="email" placeholder="ID(メールアドレス)">
<input type="text" name="lastname" placeholder="姓(ふりがな)">
<input type="text" name="firstname" placeholder="名(ふりがな)">

<input type="submit" name="submit" value="次へ" class="center">
<a href="login_err.php">戻る</a>
</form>

サーバーサイド
ps_input.php

if(isset($_POST['submit'])){

if ($_SERVER["REQUEST_METHOD"] == "POST") {
    
$email = filter_input(INPUT_POST,'email',FILTER_SANITIZE_EMAIL);
$lastname = filter_input(INPUT_POST,'lastname',FILTER_SANITIZE_STRING);  // ふりがな
$firstname = filter_input(INPUT_POST,'firstname',FILTER_SANITIZE_STRING);  // ふりがな

if(!filter_var($email,FILTER_VALIDATE_EMAIL)){
    $errors[] = "正しいEメール形式を入力してください。";
    exit;
    }

    $stmt = $dbh->prepare("SELECT * FROM users WHERE email = ? AND furigana_sei = ? AND furigana_mei = ?");
    $stmt->execute([$email, $lastname, $firstname]);
    $user = $stmt->fetch();

    
    if($user){

        $auth_key = random_int(100000,999999);

        $stmt = $dbh->prepare("UPDATE users SET auth_key = ? WHERE email = ?");
        $stmt->execute([$auth_key,$email]);
        $to = $user['email'];
        $subject = "認証キーのお知らせ";
        $message = "認証キーは以下のとおりです。".$auth_key;
        if(sendmail($to,$subject,$message)){
            header("Location:pass_input.php");
            exit;
        }else{
            $errors[] = "メールの送信に失敗しました。もう一度試してください。";
        }
    }else{
        $errors[] = "該当するユーザーは存在しません。";
    }
}
foreach($errors as $error){
    echo $error."<br/>";
}
}

HTMLフォーム

pass_input_view.php

<p>以下のメールアドレス宛に認証キーを記載したメールを送りました。<br>
メール本文内の認証キーを入力し、新しいパスワードを設定して「次へ」でお進みください。</p>
<form action="" method="post" class="login_input"> 

<input type="text" name="email" placeholder="ID(メールアドレス)">
<input type="text" name="auth_key" placeholder="認証キー(6桁半角数字)">
                       
<input type="text" name="password" placeholder="新パスワード(半角英数字8文字以上)">
<input type="text" name="password_confi" placeholder="新パスワード(確認)" >
                       
<input type="submit" name="submit" value="次へ">
                          
</form>

サーバーサイド

pass_input.php

$errors = [];

if(isset($_POST['submit'])){
    $email = filter_input(INPUT_POST,'email',FILTER_SANITIZE_EMAIL);
    $auth_key = filter_input(INPUT_POST,'auth_key',FILTER_SANITIZE_NUMBER_INT);
    $password = filter_input(INPUT_POST,'password',FILTER_SANITIZE_STRING);
    $password_confi = filter_input(INPUT_POST,'password_confi',FILTER_SANITIZE_STRING);

try{
    $stmt = $dbh->prepare('SELECT auth_key FROM users WHERE email = ?');
    $stmt->execute([$email]);
    $user = $stmt->fetch();

    if($user && hash_equals($auth_key,$user['auth_key'])){
       if($password == $password_confi){
                
          if (preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]{8,}$/', $password)) {
              $hash_password = password_hash($password,PASSWORD_DEFAULT);
              $stmt = $dbh->prepare("UPDATE users SET password = ? WHERE email = ?");
              $stmt->execute([$hash_password,$email]);
              
              header("Location:pass_comple.php");
              exit;
                
         }else{
             //バリデーション 消して大丈夫です。
             $errors[] = "パスワードは半角英数字8文字以上で、英大文字、英子文字、数字を最低1個以上含む必要があります。";
             }
        
        }else{
        
            $errors[] = "入力したパスワードが一致しません。" ;
        }
     
        }else{
        $errors[] = "認証キーが無効またはメールアドレスが間違っています。";
        
        }

    }catch(PDOException $e){
        $errors[] = "データベースエラー:".$e->getMessage();
    }
}

foreach($errors as $error){
    echo $error."<br/>";
}

説明

HTMLフォーム

<p>下記項目を入力して、「次へ」でお進みください。</p>
<form action="" method="post" class="login_input">
<input type="text" name="email" placeholder="ID(メールアドレス)">
<input type="text" name="lastname" placeholder="姓(ふりがな)">
<input type="text" name="firstname" placeholder="名(ふりがな)">

<input type="submit" name="submit" value="次へ" class="center">
<a href="login_err.php">戻る</a>
</form>

必要項目を入力してsubmitボタンを押す

//フォームの次へボタンが押されsubmitがPOSTされているか確認
if(isset($_POST['submit'])){

//$_SERVER["REQUEST_METHOD"] == "POST"が最も良い
if ($_SERVER["REQUEST_METHOD"] == "POST") {

//POSTされたものを受け取る    
$email = filter_input(INPUT_POST,'email',FILTER_SANITIZE_EMAIL);
$lastname = filter_input(INPUT_POST,'lastname',FILTER_SANITIZE_STRING);  // ふりがな
$firstname = filter_input(INPUT_POST,'firstname',FILTER_SANITIZE_STRING);  // ふりがな


if(!filter_var($email,FILTER_VALIDATE_EMAIL)){
    $errors[] = "正しいEメール形式を入力してください。";
    exit;
    }

    //POSTされた項目から当てはまるユーザーが存在するか確認
    $stmt = $dbh->prepare("SELECT * FROM users WHERE email = ? AND furigana_sei = ? AND furigana_mei = ?");
    $stmt->execute([$email, $lastname, $firstname]);
    $user = $stmt->fetch();

    //ユーザーの存在を確認した場合
    if($user){

        //メールで送る本人確認用の認証キーを生成
        $auth_key = random_int(100000,999999);

        //ユーザーのデータベースにも合言葉の認証キーを登録しておく
        $stmt = $dbh->prepare("UPDATE users SET auth_key = ? WHERE email = ?");
        $stmt->execute([$auth_key,$email]);
        $to = $user['email'];
        $subject = "認証キーのお知らせ";
        $message = "認証キーは以下のとおりです。".$auth_key;

     //ユーザーに認証用キーを送る
        if(sendmail($to,$subject,$message)){
            header("Location:pass_input.php");
            exit;
        }else{
            $errors[] = "メールの送信に失敗しました。もう一度試してください。";
        }
    }else{
        $errors[] = "該当するユーザーは存在しません。";
    }
}
foreach($errors as $error){
    echo $error."<br/>";
}
}

フォームの次へボタンが押されsubmitがPOSTされているか確認して、POSTされたものを受け取る。POSTされた項目から当てはまるユーザーが存在するか確認。

ユーザーの存在を確認した場合、メールで送る本人確認用の認証キーを生成。

ユーザーのデータベースにも合言葉の認証パスワードを登録しておく。最後にユーザーに認証用パスワードを送る。

HTMLフォームその2

<p>以下のメールアドレス宛に認証キーを記載したメールを送りました。<br>
メール本文内の認証キーを入力し、新しいパスワードを設定して「次へ」でお進みください。</p>
<form action="" method="post" class="login_input"> 

<input type="text" name="email" placeholder="ID(メールアドレス)">
<input type="text" name="auth_key" placeholder="認証キー(6桁半角数字)">
                       
<input type="text" name="password" placeholder="新パスワード(半角英数字8文字以上)">
<input type="text" name="password_confi" placeholder="新パスワード(確認)" >
                       
<input type="submit" name="submit" value="次へ">
                          
</form>

メールに送られてきた認証キーとメールアドレスを入力。

新しいパスワードを2回入力するようにする。submitボタンで入力完了。

サーバーサイドその2

$errors = [];

//POSTされたsubmitを確認
if(isset($_POST['submit'])){

  //POSTされた各値を取得して変数化
    $email = filter_input(INPUT_POST,'email',FILTER_SANITIZE_EMAIL);
    $auth_key = filter_input(INPUT_POST,'auth_key',FILTER_SANITIZE_NUMBER_INT);
    $password = filter_input(INPUT_POST,'password',FILTER_SANITIZE_STRING);
    $password_confi = filter_input(INPUT_POST,'password_confi',FILTER_SANITIZE_STRING);

try{

  //ユーザーのデータにPOSTされた認証キーと合致するもがあるか確認
    $stmt = $dbh->prepare('SELECT auth_key FROM users WHERE email = ?');
    $stmt->execute([$email]);
    $user = $stmt->fetch();

  //ユーザーとハッシュ化された認証キーと入力した認証キーが合っている場合
    if($user && hash_equals($auth_key,$user['auth_key'])){
    //2回入力した新しパスワードが同じだった場合
       if($password == $password_confi){
                
      //preg_macthで一致しているか確認
          if (preg_match('/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])[a-zA-Z0-9]{8,}$/', $password)) {
              
         //入力したパスワードを安全のためハッシュ化してユーザーのデータベースにパスワードを保存
        $hash_password = password_hash($password,PASSWORD_DEFAULT);
              $stmt = $dbh->prepare("UPDATE users SET password = ? WHERE email = ?");
              $stmt->execute([$hash_password,$email]);
              
              header("Location:pass_complete.php");
              exit;
                
         }else{
             //バリデーション 消して大丈夫です。
             $errors[] = "パスワードは半角英数字8文字以上で、英大文字、英子文字、数字を最低1個以上含む必要があります。";
             }
        
        }else{
        
            $errors[] = "入力したパスワードが一致しません。" ;
        }
     
        }else{
        $errors[] = "認証キーが無効またはメールアドレスが間違っています。";
        
        }

    }catch(PDOException $e){
        $errors[] = "データベースエラー:".$e->getMessage();
    }
}

foreach($errors as $error){
    echo $error."<br/>";
}

POSTされたsubmitを確認

POSTされた各値を取得して変数化

ユーザーのデータにPOSTされた認証キーと合致するもがあるか確認

ユーザーとハッシュ化された認証キーと入力した認証キーが合っている場合

preg_macthで一致しているか確認。

入力したパスワードを安全のためハッシュ化してユーザーのデータベースにパスワードを保存。

【広告】楽天のサービスだから超お得!