パスワードを忘れた場合、ユーザーに新しいパスワードを入力して変更し、ログインできるようにする。
全体像
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で一致しているか確認。
入力したパスワードを安全のためハッシュ化してユーザーのデータベースにパスワードを保存。