2017-01-24 12 views
2

HTML、Javascript、PHPで登録コードを書いています。以下のように(高いレベルで) 登録プロセスは次のとおりです。私の登録コードは、同じ電子メールを2回登録することを許可しています(フォームが複数回連続して非常に速く提出された場合のみ)

ユーザー:
1. HTMLフォームに自分の電子メール、名、およびパスワード(2回)を入力します。
2.「アカウントの作成」
3.ユーザのメールでメールが検索され、 が存在するかどうかが確認されます。
4.存在する場合は、既に登録されており、ログイン画面へのリンクが提供されていることが通知されます。 5.電子メールがまだ存在していない場合は、他のユーザーの詳細と一緒に私のデータベースのユーザーテーブルに挿入されます。

私のコードはこれを達成するためにはうまくいますが、 。ユーザーが「アカウントの作成」を複数回押すと、同じ電子メールアドレスが2回登録されます。これをやめるために何かできることはありますか?

ここに私のコードです:
はJQuery/Javascriptの

$("#registration_form").on("submit", function(e){ 
    //this is called when the form is submitted i.e when "create account" is pressed 
    e.preventDefault(); 

    var registration_email = $('#registration_email').val(); 
    var registration_password = $('#registration_password').val(); 
    var registration_password_confirmation = $('#confirm_registration_password').val(); 
    var registration_display_name = $('#registration_display_name').val(); 

    //validate fields and check if passwords match. 
    //all values have passed validation testing therefore make ajax request 

    var params = { 'registration_email' : registration_email, 'registration_password' : registration_password , 'registration_display_name' : registration_display_name, 'app_root_url':app_root_url}; 

     $.ajax({ 
     url: app_root_url + 'login_registration/registration_processing.php', 
     data: JSON.stringify(params), 
     type: "POST", 
     dataType: "json", 
     contentType: "application/json;charset=utf-8", 

      success: function(data){ 
      var result = data; 

      var emailAlreadyExists = result.email_already_exists; 
      if(emailAlreadyExists){ 
       //email already exists in our database and therefore the user is already registered so should use the login form 

       displayError('registration_feedback_message', 'This email already exists in the system. If you already have an account please <a href="#page-login">login here!</a>'); 

      }else{ 
       //email does not already exist in our database 

      }    

     }//end success 
    });//end ajax 


}); 

registration_processing.php(このファイルの主要部分)

include_once '../includes/app_functions.php'; 
$app_root_url = filter_var($json->app_root_url, FILTER_SANITIZE_URL); 
$email = filter_var($json->registration_email, FILTER_SANITIZE_EMAIL); 
$password = filter_var($json->registration_password, FILTER_SANITIZE_STRING); 
$display_name = filter_var($json->registration_display_name, FILTER_SANITIZE_STRING); 
//more data filtering is performed here 

$userPrivilegeID = 1; //basic user privilege 
$userHasPassword = 1; //boolean 1 or 0 

$profileImage = "images/profile_images/blank-avatar.png"; 

$results = registerUser($password, $email, $isAvatarImage, $profileImage, $userPrivilegeID, $display_name, $userHasPassword, $pdoConnection); 

//create an array to store all values that we want to send back to the client side. 
$data = array(); 
if($results['exception_occurred'] == true){ 
     $data['exception_occurred'] = true; 
     $data['exception_message'] = $results['exception_message']; 
     echo json_encode($data); 

}else{ 
     $data['exception_occurred'] = false; 
     if($results['email_already_exists'] == true){ 
      //email already exists. user is already registered and therefore has a password 
      //need to show error to user to say they are already registered and should use the login form. 

      $data['email_already_exists'] = true; 
      echo json_encode($data); 

     }else{ 
      //email didnt exist so they have been registered 
      $data['email_already_exists'] = false; 
      //create an array which we will encrypt as our JWT token 
      $token = array(); 
      $token['userID'] = $results['user_id']; 
      $token['email'] = $email; 

      $data['userID'] = $results['user_id']; 
      $data['user_is_subscriber'] = true; 
      $data['valid_user'] = true; 
      $data['userDetails'] = getProfile($results['user_id'], $pdoConnection); 

      $data['usertoken'] = JWT::encode($token, 'secret_server_key'); 
      //echo data back to ajax request on client side 
      echo json_encode($data); 
     } 
} 

(app_functions.php中)のregisterUser機能

function registerUser($password, $email, $isAvatarImage, $profileImage, $userPrivilegeID, $display_name, $userHasPassword, $pdoConnection){ 
    $data = array(); 
    try{ 
     $data['exception_occurred'] = false; 
     //first check if that email already exists just in case 
     $query = "SELECT COUNT(userID) FROM users WHERE emailAddress=:emailAddress"; 
     $statement = $pdoConnection->prepare($query); 
     $statement->bindValue(':emailAddress', $email, PDO::PARAM_STR); 
     $statement->execute(); 
     $rowCount = $statement->fetchColumn(0); 
     if($rowCount > 0){ 
      //email already exists. user is already registered and therefore has a password 
      //need to show error to user to say they are already registered and should use the login form. 
      $data['email_already_exists'] = true; 
      return $data; 
     }else{ 
      $data['email_already_exists'] = false; 

      $hashedPassword = password_hash($password, PASSWORD_DEFAULT, ['cost' => 12]); 
      $query = "INSERT INTO users (emailAddress, password, isAvatarImage, profileImage, userPrivilegeID, displayName, userHasPassword) VALUES (:emailAddress, :password, :isAvatarImage, :profileImage, :userPrivilegeID, :displayName, :userHasPassword)"; 
      $statement = $pdoConnection->prepare($query); 
      $statement->bindValue(':emailAddress', $email, PDO::PARAM_STR); 
      $statement->bindValue(':password', $hashedPassword, PDO::PARAM_STR); 
      $statement->bindValue(':isAvatarImage', $isAvatarImage, PDO::PARAM_INT); 
      $statement->bindValue(':profileImage', $profileImage, PDO::PARAM_STR); 
      $statement->bindValue(':userPrivilegeID', $userPrivilegeID, PDO::PARAM_INT); 
      $statement->bindValue(':displayName', $display_name, PDO::PARAM_STR); 
      $statement->bindValue(':userHasPassword', $userHasPassword, PDO::PARAM_INT); 
      $statement->execute(); 
      $data['user_id'] = $pdoConnection->lastInsertId(); 
      return $data; 
     } 
    }catch(PDOException $e){ 
     //throw new pdoDbException($e); 
     $data['exception_occurred'] = true; 
     $data['exception_message'] = $e->getMessage(); 
     return $data; 
    } 
} 

私が考えることができる1つの解決策は、複数のajaxリクエストを互いに近づけることができないように、「アカウントを作成」ボタンのタイマーを使用しますか?

編集

あなたのソリューションのいくつかを読んだ後、私は、電子メールフィールドはユニークな作りに探しています。ありがとう 私はphpMyAdminで作業していますので、「ユニーク」(画像で強調表示)を押すだけで簡単ですか?

enter image description here

編集2

私は一意のキーとして電子メールを作成しようと、私は次のエラーを取得:

enter image description here

編集]を3

エラーを解決するには上記(編集2で)メールアドレスフィールドの照合をutf8mb4_unicode_ciからutf8_unicode_cに変更しました私は再び "ユニーク"を押してみました。ありがとうございました

+3

重複を避ける正しい方法は、アプリケーション内で競合するクエリではなく、データベース内でユニークな制約/インデックスを使用することです。 –

+1

明らかにそうですが、それは簡単ですが、恐れている場合は、テーブルのコピーを作成し、それを他のテーブルで実行する前にテストしてください。 –

答えて

1

UNIQUE CONSTRAINTをメールボックスのデータベースに追加することができます。既に存在する電子メールを挿入しようとすると、この方法では失敗します。

+0

私は主キーとしてuserIDを持っています。プライマリキーを変更せずにEメールフィールドにUNIQUE CONSTRAINTを追加できますか?または私の主キーを再考する必要がありますか?ありがとう – Sarah

+0

主キーを変更する必要はありませんが、本当にuserIDが必要であることを確認してください。 – Ollaw

+0

ありがとうございました。あなたは私の編集を見ることができますか?だから、私はphpMyAdmin(上記の画像で強調表示されている)の表で "一意"を選択するだけですか? – Sarah

0

データが返されました。そうでない場合は、2つのオプションがあります。 elseブロック内のデータを返す代わりに、elseブロックの外側に返すか、または データを返します。それは電子メールIDを設立いますが、それがメールフィールドを作る2つの異なるアカウント

+0

それを指摘してくれてありがとう。今私はregisterUser関数でそれを見る。 – Sarah

1

に同じ電子メールIDを使用するユーザーを登録することができますので、チェックしている場合、それは偽になります戻らないとき

は、これが原因とあなたデータベースは一意です。ユーザーは自分のメールアドレスを変更したいので、私はPKをおすすめしません。

1

サーバーとクライアントの両方で検証を行うことを常にお勧めします。

この場合、前述のように、サーバー(データベース)では、電子メールフィールドにunique constraintを定義する必要があります。したがって、繰り返し電子メールは決して実際には起こりません。

私もそれに最初のクリック後、「アカウントを作成」ボタンをdisableすることをお勧めします。ボタンの名前を "...しばらくお待ちください"に変更して、操作が実行されていることを示すこともできます。サーバからの応答(成功または失敗)を取得したら、再度有効にすることができます。これにより、最初にサーバーへの不要な連続呼び出しを回避できます。

+0

あなたの助言に感謝します。私はあなたが言ったようにボタンを無効にします。 – Sarah

関連する問題