Check if username or email is taken - PHP [duplicate] - php

This question already has answers here:
How to prevent duplicate usernames when people register?
(4 answers)
Closed 6 months ago.
I am trying to check if the email or password is taken. When I type in a taken username, it says username taken, if I type in a taken email, it says email taken but if I type a taken Email AND Username, it says "Good" instead of "Username and email taken." Does anyone know why it isn't working?
$userSql = "SELECT * FROM members WHERE username='$username'";
$emailSql = "SELECT * FROM members WHERE email='$email'";
$result = mysql_query($userSql);
$result2 = mysql_query($emailSql);
$count = mysql_num_rows($result);
$count2 = mysql_num_rows($result2);
if (!empty($first_name) && !empty($last_name) && !empty($email) && !empty($username) && !empty($password)) {
if ($count != 1) {
echo "<p style=\"color: red\">Email taken, try another. You may already have an account</p>";
}
else if ($count2 != 1) {
echo "<p style=\"color: red\">Username taken, try another. You may already have an account</p>";
}
else if ($count != 1 && $count2 != 1) {
echo "<p style=\"color: red\">Username and email taken, try another. You may already have an account</p>";
}
else {
echo "<p>Good</p>";
}
It's really frustation because I have no idea why it wouldn't work.

What you should do is set a constraint in your database for unique usernames and e-mail addresses. Then, try to do an insert and catch the exception when it fails. Otherwise, you could have a condition where nearly simultaneous users try to register at the same time, and between your SELECT and INSERT statements, the username or e-mail address might be used by someone else.
ALTER TABLE `members` ADD UNIQUE INDEX `email` (`email`);
You also have a real serious problem with SQL injection. Never concatenate data directly into a query, or you risk having the data getting confused with the command. The data must be escaped. The proper way to handle this is with prepared/parameterized queries which are available with PDO.

Related

Data inserted into the database even though it already exists

I'm currently coding a registration script in PHP and my problem is that the data is still inserted into the database even though it already exists. It's probably some silly mistake or I need some else{} statement or I don't really know. The thing is that even though the email already exists in the database it stills enters it.
It does display the error just fine.
if(filter_var($email,FILTER_VALIDATE_EMAIL)){
$email = filter_var($email,FILTER_VALIDATE_EMAIL);
$email_check = mysqli_query($con, "SELECT email FROM database WHERE email='$email'");
$num_rows = mysqli_num_rows($email_check);
if($num_rows>0){
echo "The email is already in use.<br>";
}
$query = mysqli_query($con,"INSERT INTO database VALUES (NULL,'$username','$name','$email','$pwh','$date')");
}
?>
If the email is already in use it displays the echo "The email is already in use." just fine, yet it still inserts it. What am I missing? I already tried using 'else' variable yet nothing helped.
Your if only echo something, then you do the INSERT no matter what. Some solution :
if(filter_var($email,FILTER_VALIDATE_EMAIL)){
$email = filter_var($email,FILTER_VALIDATE_EMAIL);
$email_check = mysqli_query($con, "SELECT email FROM database WHERE email='$email'");
$num_rows = mysqli_num_rows($email_check);
if($num_rows>0){
echo "The email is already in use.<br>";
}
// ADD A ELSE SO YOU INSERT IF YOU HAVE NOTHING
else {
$query = mysqli_query($con,"INSERT INTO database VALUES (NULL,'$username','$name','$email','$pwh','$date')");
}
}
Now you can prevent it from your database too :
Add a UNIQUE INDEX on the column email from your table database
Use INSERT IGNORE now, so it will insert if the email is not used and ignore if email is already used
And last, use prepare statement and bind param to avoind SQL injection !
Hope it helps
Your if is fine, but you then proceed to always do the insert. This is because you have put it outside the if.
what you should do is :
if(!$num_rows <= 0){
<insert statement>;
}
else {
echo "The email is already in use.<br>";
}
write this statement inside else block
else
{
$query = mysqli_query($con,"INSERT INTO database VALUES (NULL,'$username','$name','$email','$pwh','$date')");
}

PHP - Check If Username Exists Or If Submitted Username Is Current

I'm trying to check if the entered username already exists or if the entered username is the current username.
I've Googled various SO questions but none seem to check if the current username is the submitted one.
The problem with the following code; it doesn't matter if the username is taken or not, it will still let you save.
$stmt = $engine->runQuery("SELECT user_name, user_email FROM users WHERE user_name=:username OR user_email=:email");
$stmt->execute(array(':username'=>$username, ':email'=>$email));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if(strtolower($row['user_name']) == strtolower($username) || $username !== $row['user_name']) {
$engine->authapi(false, 'Sorry, username is already taken. Please choose a different one.');
} elseif(strtolower($row['user_email']) == strtolower($email) && $email !== $_SESSION['user_email']) {
$engine->authapi(false, 'Email is already registered. You cannot use the same emails for multiple accounts.');
} else {
// save
}
How can I make it so it checks if the username is taken or not, and at the same time check if the submitted username is the current username (if so, let the user save)?
Actually, there are several issues in your code.
1) Your SQL. You can fetch more than one row here, for example you have two entries in your database, username: maio290, e-mail: a#foo.bar and username: maio291, e-mail: b#foo.bar. Now your user enteres username: maio290 and e-mail: b#foo.bar which will result in two entries selected. Most likely an edge case, but a valid one.
2) Your if: You're comparing strtolower($row['user_name']) == strtolower($username) OR $username !== $row['user_name']) - the second one doesn't make any sense with your error. Since that means: "hey, your user is not in our database, please take a different one" Also, the first comparision could be a lot nicer with using strcasecmp.
I would really split these two options, since it's a lot better to read and you don't have the problem with two selectable rows. Also, you let your database handle the comparision.
Therefore I would write the code like that:
<?PHP
// Select if username is taken
$stmt = $engine->runQuery("SELECT user_name FROM users WHERE user_name=:username");
$stmt->execute(array(':username'=>$username));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if(count($row) != 0)
{
$engine->authapi(false, 'Sorry, username is already taken. Please choose a different one.');
// I would actually return here, so we wouldn't need an else
}
else
{
// check if e-mail is registred
$stmt = $engine->runQuery("SELECT user_email FROM users WHERE user_email=:email");
$stmt->execute(array(':email'=>$email));
$row = $stmt->fetch(PDO::FETCH_ASSOC);
if(count($row) != 0)
{
$engine->authapi(false, 'Email is already registered. You cannot use the same emails for multiple accounts.');
}
else
{
// store
}
}
?>

MySQL multiple queries not working

Problem has been solved
I have created a form that processes the changing of user information from the admin side e.g. the admin changes a user's username and/or email. I am having trouble processing multiple queries.
For example, if the admin changes the username, the query works. If the admin changes the email address, the query works. But if the admin changes the username and email at the same time through the form then only the username changes.
Any ideas? I will submit my code but I will change variables for security reasons etc. Also, anything in capitals has been changed for security reasons. The code is all correct for each individual function because as I said, if I ONLY change the email, it works and actually changes. But if I change the username AND email, only the username will change despite the fact the email query runs and it echo's the email has been changed!
Also, it is worth noting that all of the fields e.g. username field and email field are part of one form that submits to one page.
if (isset($_POST['SUBMIT_BUTTON_PRESSED'])) {
//Gather all inputs from the form and sanitise it.
//REMOVED FOR SECURITY REASONS.
if($USERNAME_NEW != "") {
if($USERNAME_NEW == $CURRENT_USERNAME) {
echo "You have entered the username you are already using. Please enter a different username.";
} else {
$CHECK_USERNAME = "SELECT USERNAME_ROW FROM USERS_TABLE WHERE username='$USERNAME_NEW'";
$RUN_QUERY = mysqli_query($CONNECTION INFO, $CHECK_USERNAME);
$RESULT = mysqli_num_rows($RUN_QUERY);
if($RESULT > 0) {
echo "That username already exists. You cannot use that username again. Please enter another username.";
} else {
$editing_username = true;
$USERNAME = $NEW_USERNAME; //NOT NEEDED BUT IT STILL WORKS
$THE_SQL_QUERY = "UPDATE USER_TABLE SET username='$USERNAME' WHERE username='$ORIGINAL USERNAME'";
$RUN_THIS_QUERY= mysqli_query($CONNECTION INFO, $THE_SQL_QUERY);
echo "The user's username has been changed to: ". $USERNAME;
}
}
}
if($EMAIL != "") {
if($EMAIL == $CURRENT_EMAIL) {
echo "You have entered the same email address to the one you are already using. Please enter a different email address.";
} else {
$CHECK_EMAIL = "SELECT USERS_EMAIL FROM USER_TABLE WHERE username='$USER'";
$CHECK_EMAIL_QUERY = mysqli_query($CONNECTION_INFO, $CHECK_EMAIL);
$RESULT = mysqli_num_rows($CHECK_EMAIL_QUERY);
if($RESULT > 0) {
echo "That email already exists. You cannot use that username again. Please enter another username.";
} else {
$editing_email = true;
$THE_NEW_EMAIL = $FINAL_EMAIL_THING; // AGAIN NOT NEEDED BUT STILL WORKS
$THE_SQL= "UPDATE USER_TABLE SET USER_EMAIL='$EMAIL' WHERE username='$USER' LIMIT 1"; // REMOVED THE LIMIT 1, STILL DOESN'T WORK
$RUN_THIS_QUERY = mysqli_query($CONNECTION, $THE_SQL);
if($RUN_THIS_QUERY) {
echo "The user's email has been changed."; // EVEN WHEN BOTH FIELDS ARE SUBMITTED THIS WORKS SO THE QUERY IS RUNNING BUT THE EMAIL DOESN'T CHANGE
}
}
}
}
Thanks for the help! Also, no un-witty remarks about how my question is structured etc. because I don't care to be honest. I just want this code working to be honest because I've been working on it for a while. This may be something simple or I might be using the wrong approach for this type of form submission.
Remember: THIS CODE DOES WORK WHEN I SUBMIT EACH FIELD SEPARATELY!
Its very hard to figure out as you are not producing the real code.
I think you have missed something here.
As you are using USER_NAME as key in the SQL's, make sure that you are using the updated username in the second sets of SQL (to update the email) as they are already replaced by the first SQL.
And there is no security risk while showing your codes snippets to someone else. Hide only the username/passwords or Identities. :)

I don't know what's wrong with this code SQL

I'm new to PHP and Mysql, for some reason it only checks for statement if($email == $result2 ) wether the input is username or email. I don't know why? can someone explain it logically, i'm stuck for hours figuring it out. :( Thanks Please be kind.
<?php
session_start();
include_once("connect.php");
$email = $_POST['email'];
$username = $_POST['username'];
//echo $_POST['email'];
if(isset($_POST['email']) )
{
$extract= mysql_query("SELECT username, email FROM users");
$resultq = mysql_num_rows($extract);
while($row= mysql_fetch_array($extract))
{
$result = $row['username'];
$result2 = $row['email'];
//$pass = $_POST['pass'];
if($email == $result2 )
{ //check if there is already an entry for that username
echo "Email Address is already used!";
exit(); //break;
}
if ($username == $result )
{
echo " Username is already Taken!";
//mysql_query("INSERT INTO users (Username, Password) VALUES ('$user', '$pass')");
//header("location:index.php");
exit(); //break;
}
else
{
}
}
}
It's behaving as written. If either if() test succeeds, you tell the script to exit().
Remove the exit() calls...
You also really REALLY need to learn about WHERE clauses in queries. You are sucking across your entire user table and comparing the records one at a time. This is the equivalent of driving to the grocery store, buying up the ENTIRE store's inventory, driving it home... then throwing it all in the garbage because all you really wanted was one candy bar.
I think you better use unique in your email and username column, then you don't need to check it anymore, mysql will do that for you!
Does it go into the second if statement ( if ($username == $result ) ) after you comment out the first one ( if ($username == $result )) ?
If so, then it keeps hitting that exit() function.
Guys i kinda guessed the answer from combining some of your comments. for some reason i need to include isset($_POST['username']) along with isset($_POST['email']) in order for my if Statements to be all executed... perhaps it was the isset checking if there is a value for username.
try this
if($email == $result2 )
{ //check if there is already an entry for that username
echo "Email Address is already used!";
//---------removed that line
}
else if ($username == $result ) //add else if instead of if
{
echo " Username is already Taken!";
//mysql_query("INSERT INTO users (Username, Password) VALUES ('$user', '$pass')");
//header("location:index.php");
//----------removed that line
}
else
{
}
EDIT:
change this
if(isset($_POST['email']) )
to
if(isset($_POST['email']) or isset($_POST['username']))
this to check them both. you are checking just email thats why you dont get the second if.
change this line the following line:
$extract= mysql_query("SELECT username, email FROM users");
Then use where clause as follows:
$extract= mysql_query("SELECT username, email FROM users where username='$username' and email='$email'");

New PHP app - Salting and securing user passwords

I am setting up a new PHP app and would like to learn to salt and secure user password. I am unsure about which step during registration I need to do this at. Also, do I need to change my login forms as well?
if(isset($_POST['submit'])){
//protect and then add the posted data to variables
$username = protect($_POST['username']);
$password = protect($_POST['password']);
$passconf = protect($_POST['passconf']);
$email = protect($_POST['email']);
//check to see if any of the boxes were not filled in
if(!$username || !$password || !$passconf || !$email){
//if any weren't display the error message
echo "<center>You need to fill in all of the required filds!</center>";
}else{
//if all were filled in continue checking
//Check if the wanted username is more than 32 or less than 3 charcters long
if(strlen($username) > 32 || strlen($username) < 3){
//if it is display error message
echo "<center>Your <b>Username</b> must be between 3 and 32 characters long!</center>";
}else{
//if not continue checking
//select all the rows from out users table where the posted username matches the username stored
$res = mysql_query("SELECT * FROM `users` WHERE `username` = '".$username."'");
$num = mysql_num_rows($res);
//check if theres a match
if($num == 1){
//if yes the username is taken so display error message
echo "<center>The <b>Username</b> you have chosen is already taken!</center>";
}else{
//otherwise continue checking
//check if the password is less than 5 or more than 32 characters long
if(strlen($password) < 5 || strlen($password) > 32){
//if it is display error message
echo "<center>Your <b>Password</b> must be between 5 and 32 characters long!</center>";
}else{
//else continue checking
//check if the password and confirm password match
if($password != $passconf){
//if not display error message
echo "<center>The <b>Password</b> you supplied did not math the confirmation password!</center>";
}else{
//otherwise continue checking
//Set the format we want to check out email address against
$checkemail = "/^[a-z0-9]+([_\\.-][a-z0-9]+)*#([a-z0-9]+([\.-][a-z0-9]+)*)+\\.[a-z]{2,}$/i";
//check if the formats match
if(!preg_match($checkemail, $email)){
//if not display error message
echo "<center>The <b>E-mail</b> is not valid, must be name#server.tld!</center>";
}else{
//if they do, continue checking
//select all rows from our users table where the emails match
$res1 = mysql_query("SELECT * FROM `users` WHERE `email` = '".$email."'");
$num1 = mysql_num_rows($res1);
//if the number of matchs is 1
if($num1 == 1){
//the email address supplied is taken so display error message
echo "<center>The <b>E-mail</b> address you supplied is already taken</center>";
}else{
//finally, otherwise register there account
//time of register (unix)
$registerTime = date('U');
//make a code for our activation key
$code = md5($username).$registerTime;
//insert the row into the database
$res2 = mysql_query("INSERT INTO `users` (`username`, `password`, `email`, `rtime`) VALUES('".$username."','".$password."','".$email."','".$registerTime."')");
//send the email with an email containing the activation link to the supplied email address
You absolutely must read this article: Enough with the rainbow tables.
Summary: If you're not using BCrypt, you're doing it wrong. No ifs, no buts. (This also means that all the suggestions to use MD5 or SHA-1 or SHA-512 or anything else are wrong too.)
As for when you do it, it should be sometime before you insert it into the DB but after you check it for errors.
Some suggestions though.
Instead of nesting the ifs during error checking so that if username fails, password doesn't get checked, and if password fails, passconf doesn't get checked try something like this:
$errors = array();
if(strlen($username) > 32 || strlen($username) < 3)
{
$errors['username'] = "Username must be between 3 and 32 characters.";
}
else
{
$res = mysql_query("SELECT * FROM `users` WHERE `username` = '".$username."'");
$num = mysql_num_rows($res);
if($num == 1)
{
$errors['username'] = "Username already exists!";
}
}
if(strlen($password) < 5 || strlen($password) > 32)
{
$errors['password'] = "Password must be between 5 and 32 characters.";
}
else if($password != $confpass)
{
$errors['password'] = "Passwords do not match.";
}
etc. etc. etc. so that each field is checked and errors returned if there are any. Then you do something like this at the end:
if(!count($errors)) //or if(count($errors) == 0)
{
//code to process login/registration/whatever Do password hashing here.
}
else
{
//There were errors, do something else
}
This way you get all errors, so you can tell the user everything that's wrong with their input at once, and the code isn't as deeply nested.
Also, the people having the flame war on what hashing algorithm to use above, just ignore them unless you're trying to create a US Government or Corporate application. No attackers will care enough to actually attack otherwise, unless your application gets popular enough to warrant an attack. It is important that you hash it in some way though.
SECURITY IS HARD. Don't do it yourself but let the exports figure it out. You could read there specs/implementations(if open):
openid
google friend connect
facebook connect
twitter single sign in
just to name a few options.

Categories